Claude is genuinely good at building full applications. It can scaffold a React app, wire up logic, and respond intelligently to feedback. But in most setups, it’s stuck in a browser chat or a CLI that isn’t connected to anything live.
We wanted to see what would happen if we gave Claude a proper development environment. Something that feels close to a real devbox, where it can write files, run a local server, and update code as you talk to it.
So we built one.
Nightona sets up a simple interface running on Cloudflare Workers, combined with Claude running inside a Daytona-managed environment. You can start with a simple React template, ask Claude to build a feature, and watch the changes happen live in your browser.
It’s a lightweight, self-hosted setup for AI-native development. And it actually works.
Try it at github.com/ghostwriternr/nightona
What Nightona Is
Nightona is a self-hosted development environment that connects Claude's natural language coding with a live React project. It runs in a Daytona sandbox, gives Claude full file access, and shows a live preview of your app as it evolves.
You get a real project, not just a code snippet. It comes with:
- React
- TypeScript
- Tailwind CSS
- shadcn/ui
- Vite dev server
You write prompts. Claude writes code. The browser updates instantly.
How We Built It
We started with the basics: a React + TypeScript template running inside a Vite dev server. Then we added Daytona to manage the workspace. Daytona gave us a persistent, sandboxed environment that could install dependencies, expose ports, and keep state across sessions.
1// Create new sandbox if none exists or previous one failed23const sandbox = await daytona.create({4 snapshot: CLAUDE_SNAPSHOT_NAME,5 user: 'claude', // Use 'claude' user instead of root6 envVars: { ANTHROPIC_API_KEY: env.ANTHROPIC_API_KEY },7 public: true // Make preview links publicly accessible8});910// Or find an existing one by id11const sandbox = await daytona.findOne({ id: sandboxState.sandboxId });
Inside that environment, we set up Claude Code CLI. This lets Claude receive prompts and make edits directly to the file system.
1FROM node:22.17.023# Install Claude Code and PM2 globally4RUN npm install -g @anthropic-ai/claude-code
After building the Dockerfile, we created a snapshot on Daytona so that the image can be pre-warmed and new sandboxes created instantly.
1const claudeImage = Image.fromDockerfile("Dockerfile");2await daytona.snapshot.create({3 name: CLAUDE_SNAPSHOT_NAME,4 image: claudeImage,5});
To let users see changes live, we ran a Vite server inside the sandbox and made it available in the browser. That gave us fast refresh, hot module reloading, and instant feedback.
On the Cloudflare side, we wrote a Worker that serves the frontend and proxies requests to Claude. The frontend has two panes: a chat interface for talking to Claude, and a live preview for watching the app update. The Worker sends your prompt to the Daytona sandbox, waits for Claude to process it, and then the Vite preview reloads when the files change.
1const previewInfo = await sandbox.getPreviewLink(3000);
Durable State with Durable Objects
Daytona’s sandboxes have persistent state, but we needed our application to connect to the same sandbox every time, and have a simple way to retain message history. Durable objects made both of these super simple - and set the stage for future features like rollbacks or code suggestions with approval.
export class SandboxManager extends DurableObject {
1export class SandboxManager extends DurableObject {2 constructor(ctx: DurableObjectState, env: Env) {3 super(ctx, env);4 }56 async getSandboxState(): Promise<SandboxState> {}7 async setSandboxState(sandboxId: string): Promise<void> {}8 async resetSandboxState(): Promise<void> {}9 async setDevServerUrl(url: string): Promise<void> {}1011 async addMessage(message: Message): Promise<void> {}12 async clearMessages(): Promise<void> {}13}
Finally, we used Wrangler to deploy everything. The Worker uses secrets to securely store Claude and Daytona API keys. The rest is just static assets and a few API routes.
What you can do with it
Once the environment is up, you can prompt Claude to:
"Create a landing page for a coffee shop with a hero section and menu"
"Add a dark mode toggle to the top right corner"
"Make the todo items draggable to reorder them"
"Add a search bar to filter the items"
"Style this with a modern gradient background"
Claude handles everything from scaffolding to refactoring. You don’t need to tell it where the file is or how to import a component. It figures it out. Each edit builds on the last. Your browser updates with every change.
How it works:
Nightona connects four core parts:
Claude Code CLI: Receives prompts and edits the file system
Daytona: Runs the dev environment with persistence
Cloudflare Workers: Routes prompts and hosts the frontend
Vite Dev Server: Runs the live preview inside Daytona
Flow:
You type into the browser chat interface
The Cloudflare Worker sends the prompt to Claude in Daytona
Claude updates files
Vite server reloads the browser preview
It feels tight and responsive. You can keep building without restarting anything.
What we learned
A live preview changes how you write prompts
Instant feedback makes it feel like pair programming. Instead of crafting one perfect instruction, you try something, see what changes, and follow up. The development loop becomes faster and more natural.

Daytona gave us stable environments without overhead
We didn't have to worry about setting up containers or maintaining state. Daytona let us treat dev environments like repeatable, programmable machines that still felt persistent when we needed them to be.

Cloudflare Workers handled the glue with minimal effort
We used Workers to connect the UI, Claude, and the environment. There was no backend logic to maintain and no servers to manage. It made the system feel simpler than it really was. Just running npm run deploy
takes care of all the infrastructure needed to scale infinitely.
Final thoughts: building a dev environment Claude can actually use
This project wasn’t about making a flashy demo. It was about giving a capable model the right environment to do useful work. When you let an AI operate inside a proper devbox, it starts to feel like a teammate. Not perfect, but fast, adaptable, and genuinely helpful.
The combination of Claude, Daytona, and Cloudflare gave us something that felt smooth to use and surprisingly easy to extend. We didn’t need a massive framework or complex orchestration. Just good tools with clean edges.
We think this model of lightweight, self-hosted AI environments has a lot of room to grow. It could power onboarding flows, internal tools, rapid prototyping, and more collaborative development experiences.
You can run Nightona yourself and start building full React apps by talking to Claude.