# Contents

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 failed
2
3const sandbox = await daytona.create({
4 snapshot: CLAUDE_SNAPSHOT_NAME,
5 user: 'claude', // Use 'claude' user instead of root
6 envVars: { ANTHROPIC_API_KEY: env.ANTHROPIC_API_KEY },
7 public: true // Make preview links publicly accessible
8});
9
10// Or find an existing one by id
11const 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.0
2
3# Install Claude Code and PM2 globally
4RUN 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 }
5
6 async getSandboxState(): Promise<SandboxState> {}
7 async setSandboxState(sandboxId: string): Promise<void> {}
8 async resetSandboxState(): Promise<void> {}
9 async setDevServerUrl(url: string): Promise<void> {}
10
11 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:

  1. You type into the browser chat interface

  2. The Cloudflare Worker sends the prompt to Claude in Daytona

  3. Claude updates files

  4. 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.

Nightona UI
Nightona UI

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.

Daytona Sandbox Overview
Daytona Sandbox Overview

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.

Tags::
  • ai-native
  • dev environment
  • claude
  • cloudflare
  • daytona
  • react
  • vite
  • live preview
  • containers
  • sandbox
  • coding assistant
  • developer tools