Kide - Code-first CMS for Astro
██╗ ██╗██╗██████╗ ███████╗ ██║ ██╔╝██║██╔══██╗██╔════╝ █████╔╝ ██║██║ ██║█████╗ ██╔═██╗ ██║██║ ██║██╔══╝ ██║ ██╗██║██████╔╝███████╗ ╚═╝ ╚═╝╚═╝╚═════╝ ╚══════╝
Kide is a code-first CMS for Astro. Define collections once in TypeScript and get database tables, validation, types, a local API, and an editor-ready admin.
// one file for four outputs.
export default defineCollection({
slug: "posts",table: posts
drafts: true,status column
fields: {
title: fields.text({ required: true }),text NOT NULL
body: fields.richText(),json
author: fields.relation({
collection: "authors",fk → authors.id
}),
},
});
// generated on save:
// drizzle tables, zod validation, typescript types, admin UI
~/projects ❯ pnpx create-kide-app
┌ ▣ Create Kide CMS Project
│
◇ Project name
│ pispala-punx-club
│
◇ Starter template
│ Marketing site (pages with blocks, blog, menu, contact form)
│
◇ How do you want the CMS runtime?
│ Package (@kidecms/core dependency)
│
◇ Where will you deploy?
│ Cloudflare
│
◇ Template ready
◇ Configuration applied
◇ Dependencies installed
◇ Schema generated
│
◆ Set up Cloudflare resources now? (creates D1 database and R2 bucket)
│ ● Yes / ○ No
└ continues on the next tab →
## Prompts and flags
Answer the prompts, or pass every answer up front and skip them. Supplied flags skip their prompts, nothing else changes.
```sh
pnpm create kide-app my-site \
--starter=marketing --mode=package \
--target=cloudflare --no-github
```
- --starter= blank | marketing
an empty schema, or a starter that can seed example content
an empty schema, or a starter that can seed example content
- --mode= package | embedded
thin project on @kidecms/core, or the full source in src/cms. Eject later, one-way.
thin project on @kidecms/core, or the full source in src/cms. Eject later, one-way.
- --target= local | cloudflare
Node + SQLite + local files, or Workers + D1 + R2
Node + SQLite + local files, or Workers + D1 + R2
- --seed / --no-seed
example content for the local target
example content for the local target
- --no-github --no-dev --no-cloudflare-setup
skip the GitHub repo, the dev server, or provisioning
skip the GitHub repo, the dev server, or provisioning
> Clones the latest release, wires the target adapters, installs, generates the schema. source ↗
◇ Set up Cloudflare resources now?
│ Yes
│
◇ Logged in to Cloudflare (wrangler)
◇ D1 database created
◇ R2 bucket created
◇ Migrations generated
◇ Migrations applied to remote D1
│
◇ Deploy to Cloudflare now?
│ Yes
│
◇ Deployed to Cloudflare
│
◇ 🎉 Your Kide CMS is live╮
│ Live at: https://my-site.workers.dev│
│ Admin: https://my-site.workers.dev/admin│
│ │
│ cd my-site│
│ Local development: pnpm dev│
│ Redeploy: pnpm run deploy│
├╯
│
└ Project created!
~/projects/my-site ❯
## Deploying to Cloudflare
Say yes and the scaffolder logs into wrangler, creates the D1 database and R2 bucket, applies migrations, deploys, and prints your URLs. The generated config is plain wrangler:
```toml
[[d1_databases]] binding = "CMS_DB"
[[r2_buckets]] binding = "CMS_ASSETS"
[triggers] crons = ["* * * * *"] # publishing
```
Skipped provisioning? You can do it manually:
```sh
pnpm dlx wrangler d1 create my-site-db
pnpm dlx wrangler r2 bucket create my-site-assets
pnpm dlx wrangler d1 migrations apply my-site-db --remote
pnpm run deploy
```
> Deploying to Node instead? See docs.kide.dev/deploy ↗
## Astro integration, no plugin API
Kide is not a headless service your site calls. It is an Astro integration in your repo: collections in TypeScript, content read through an import, the admin served by your own app, pages cached by Astro’s route cache with tag invalidation.
There is no plugin API. You extend it the way you extend any code you own. Small needs are hooks:
```ts
hooks: {
beforeCreate(d) { d.excerpt ??= excerptOf(d.body); return d; },
afterPublish(_, c) { c.cache?.invalidate({ tags: ["posts"] }); },
},
```
Need more?
pnpm exec kide eject moves the runtime, routes, and admin into src/cms. Read it, change it, audit it.> Package mode when you want a dependency. Embedded when you want the source.
## What editors get
Your schema stays in TypeScript. Editors get a complete admin out of the box.
- [x] Rich text + blocks — structured when it matters
- [x] Assets that behave — folders, focal points, optimization
- [x] Live preview — edit in the admin, see the page
- [x] Draft, schedule, restore — publishing without archaeology
- [x] Field-level i18n — translate only what needs it
- [x] Roles + review — access rules, review, audit trail
# recent entries · demo.kide.dev/admin
Front PageFront Pagepublished
Features PagePagepublished
AboutPagepublished
Getting Started with Kide CMSPostpublished
Designing Content Models That ScalePostpublished
The Local API PatternPostpublished
Deploying to CloudflarePostpublished
Building Custom Block TypesPostpublished
Access Control and RolesPostdraft
# open the admin to edit any of these