Project structure
Where the app, the CMS-driven site, the database and the Cloudflare config live.
Emberstack follows the usual Astro layout. Public pages come from EmDash, the app lives under /app, and Cloudflare configuration sits in wrangler.jsonc.
Top level
Path | What it holds |
|---|---|
| Application code |
| SQL migrations for the app database, generated by Drizzle |
| EmDash's starter content: collections, blocks, menus, settings, pages and posts |
| The Markdown source for these docs |
|
|
| Static files served as-is, including |
| Conventions for AI coding agents working on the project |
| Worker name, bindings, domains and variables |
| Astro, the Cloudflare adapter, EmDash and its plugins |
| Drizzle Kit settings for migrations |
Inside src
Path | What it holds |
|---|---|
| The Worker entry. It wraps EmDash's Worker and adds the maintenance cron |
| Reads the Better Auth session and sets the signed-in user and team on every request |
|
|
| Auth, payments, email, Datastar helpers and password hashing |
| Astro actions for account, team and checkout |
| The signed-in dashboard: notes, team, settings, activity |
| Better Auth's handler and the Stripe routes |
| Docs and blog, rendered from EmDash |
| EmDash pages, including the home page |
| The UI component set |
| Marketing blocks for EmDash pages |
| Callout, steps, link card and file tree blocks for docs |
|
|
| Tailwind, daisyUI themes and site styles |
| Name and custom scripts for the app and sign-in pages |
Two databases
The app and the CMS each have their own D1 database. DB holds users, teams, sessions, notes and activity. CMS_DB holds pages, posts, menus and settings, with uploaded media in the MEDIA R2 bucket. They're separate because both systems create a users table. See Database and The CMS.