AstroCraft — home
AstroCraft
Buy a licence

The native Astro CMS that reads the schema you already wrote.

AstroCraft mounts into an Astro site you already have. It adds an admin that edits your own markdown, commits it as the signed-in author, and never asks you to describe your content twice.

no config.ymlno second schemanothing to keep in sync

src/content.config.ts

your repo

the only description of this collection

/admin/blog/ethiopia-guji

5 fields

string
string?
date
string[]
originroastingguji
NEW
ImageRef?

Not just an editor. The whole workflow.

Validation, the build gate, the commit, the push, and who is allowed to do any of it. All of it inside your own Astro server. Nothing calls out.

title

z.string()

Text
introspected

slug

— not a schema field

Slug · read-only
override

pubDate

z.union([z.string(), z.date()])…

Raw YAML
introspected

pubDate: z.union([z.string(), z.date()]).transform((v) => new Date(v))

The output type differs from the input: string | Date goes in, Date comes out. Introspection reads the shape and cannot conclude a control from it.

Raw YAML — what the file actually holds

pubDate: 2023-10-27T10:00:00.000Z

Choose a widget for this field in Field overrides →

updatedDate

z.coerce.date().optional()

Date
introspected

categories

z.array(z.string())

Tags
introspected

authors

z.array(reference('authors'))

Reference → authors
introspected

description

z.string()

Long textoverride
introspected

draft

z.boolean()

Toggle
introspected

heroImage

image().optional()

Image
introspected

body

— the markdown body

Markdown
introspected

Your schema is the schema

src/content.config.ts · 10 fields

Last pushYesterday, 16:04
Branchmain
Commita3f9c21
Not yet pushed3 entries

Recent pushes

  • Yesterday, 16:04Sarah Chena3f9c21 · 1 entry
  • 22 Oct, 09:12Dominique7c1e40b · 2 entries
  • 21 Oct, 18:40Dominiquee93b118 · 1 entry
  • 20 Oct, 11:274af0d92 · pushed outside the CMS
  • 19 Oct, 15:02Marcus Johnsonb2d7c31 · 2 entries

It pushes. You deploy.

your host builds from this branch

latte-handover.jpg
latte-handover.jpg2560 × 1707 · 2.9 MB
cup-on-beans.jpg
cup-on-beans.jpg1920 × 1280 · 1.0 MB

It shrinks what you committed

128 assets · 34 oversized

Validate frontmatter3 entries against the emitted schema — milliseconds, no build40ms
astro buildThe gate. Nothing is committed until this passes.4.2s
Commit 3 entriescontent(blog): update 3 entriesrunning
Push to origin/mainSeparate from the commit, and separately recoverable

The build is the gate

validate · build · commit · push

astro.config.mjs+ 1 line
src/actions/index.tsnew
+ 2 more filesnew
src/data/untouched

Four files, and one line

four minutes on a site that builds

PersonRoleStatusLast active
DRDomi Roussel(you)[email protected]
AdminActivenow
SCSarah Chen[email protected]
EditorActive2 hours ago
MJMarcus Johnson[email protected]
EditorActiveyesterday
ERElena Rodriguez[email protected]
EditorActive2 days ago
PSPriya Sharma[email protected]
EditorInvitedinvite sent 3 days ago
SOSam Okafor[email protected]
EditorDisabledlast seen 5 weeks ago

Editors, and clients

1 admin · 5 editors · 1 invite pending

A developer changed this file on disk.

git pull, or an editor open on the same project, can move a file under the CMS. Nothing is overwritten.

Changed underneath you

both versions, field by field

No account, no licence server, no phone–home — all of it runs where your repo is.

It writes to your repo, not to a database.

Publishing is git commit && git push, so an edit is a commit by the person who made it. Nothing lives in a service you would have to migrate off later.

git log · the last 4 commits

meridian-coffee

  • a3f19c2Sarah Chencontent(blog): update "ethiopia-guji"
  • 7e0b41dMarcus Reidcontent(blog): create "cupping-notes"
  • 1c94ee8Sarah Chencontent(pages): update "wholesale"
  • 0d2a7f5Marcus Reidcontent(team): update "sarah-chen"

committer astrocraft <[email protected]>

Two people editing show up as two authors. One committer, because the server is what holds the checkout.

save.ts:75

the second save

{

saved: false,

sha: 'a3f19c2…',

raw: '---\ntitle: How we…'

}

A mismatch comes back as data, not an error — the dialog needs the file to show you.

publishing as
  • 1,338 tests across 60 files
  • 61 kB gzipped on the editor route

The screen you hand to the client.

Sections are your own components. The client edits declared props, never raw CSS, so the worst thing they can do to your design system is fill in a field and it arrives as a diff you read before it merges.

Open the live composer
OverviewBlogPagesTeamImagesSettings

PagesWholesale/wholesale

Unsaved changes

Already on this page

sections/6

Hero
HeroSplit
Banner
FeatureSplit
FeatureGrid
RichText

sections/proof/3

Stats
Quote
Logos

sections/action/3

CTABand
Newsletter
ContactForm

Not composable

blocks/items only

primitives/not sections

src/components/12
1280 PX
50%
Meridian
CoffeeWholesaleVisitJournalOrder
Hero

For cafés and grocers

Wholesale coffee for people who care where it came from

Three picking passes, twelve years of direct relationships, and a published roast profile for every lot we sell.

Open an account

Three passes, not one

Cherries are picked over three passes rather than stripped in one. It is slower and it costs more, and it is the whole reason the cup tastes like stone fruit instead of toast.

How we source

12 yrs

Direct trade

40+

Café partners

3

Picking passes

Open a wholesale account

Talk to us

src/pages/wholesale.astro BaseHero

4 SECTIONS

Hero

sections/Hero.astro

titlestring

eyebrowstring

align"left" | "center"

tone"warm" | "cool"

imageImageRef

ReplaceRemove

badgesBadge[]

2 items

Type not readable — round-tripped untouched

Writes to

src/pages/wholesale.astro

A three-pane editor has no honest phone layout — scroll the panel sideways to reach the library and the props.

Open the demo workspace

Save all day. Nothing moves until you publish.

Edits autosave into the working tree, not onto the site. The published site keeps serving the last commit that was pushed, so an unfinished sentence is never live.

src/content/blog/ethiopia-guji.mdx

the editor

Unpublished changes

How we roast the Ethiopia Guji

DRAFT24 October 2026

Beans grown above 2,000 metres are denser, so they take heat differently. We drop the charge temperature by twelve degrees and stretch the development phase.

Roast ProfileBLOCKEdit block

Charge 196°C · first crack 9:20 · development 22% · drop 204°C

Saved just now412 words · 2 min read

Your client edits. You approve.

A client account cannot publish. Their changes arrive as a field-by-field diff — was on top, now underneath — and one approval is one commit carrying the name of the person who made it.

content(blog): update three-passes-wet-mill

review & publish

1 of 3 approved

Three passes on the wet mill

Needs your review

/blog/three-passes-wet-mill · Sarah Chen · 4h ago

TITLEchanged
wasThree passes on the mill
nowThree passes on the wet mill
TAGSone added
wasprocessingwashed
nowprocessingwashedsourcing
Preview entry
Request changes…
2 need your reviewcontent(blog): update three-passes-wet-mill

The images are in your repo too.

Uploads land in src/assets and are committed like anything else. Alt text that is missing and sources above 1920px are counted rather than nagged about, because AstroCraft does not run your build.

one copy per image · committed to git

images

src/assets/ · 122 files

  • wet-mill-2026.jpg

    2400 × 1350 · 3.1 MB

  • guji-cherries.jpg

    1600 × 2500 · 1.4 MB

  • guji-cup-hero.jpg

    1920 × 1280 · 820 KB

  • roast-drum-charge.jpg

    1920 × 1272 · 760 KB

  • kenya-parchment.jpg

    2400 × 1600 · 2.2 MB

  • ALT

    kenya-branch.jpg

    1920 × 1280 · 680 KB

12 missing alt text184 MB in repository

Buy it once. A year of updates, then the build is yours to keep.

Three tiers, and the only thing that changes between them is how many sites the key covers — the terms below are identical for all three. An unlicensed copy is not a trial; it is the same build with a reminder in it.

Choose a licence tier

Renew for another year of updates whenever you want, or never. Nothing stops working.

Every licence

  • Updates for a year — the version you bought never expires
  • Verified offline — no licence server
  • Nothing phones home, ever
  • Nothing locked behind the key
  • Never watermarked or throttled
  • Entries stay markdown in your repo
  • Unlicensed copies keep working
  • No per-seat and no monthly cost
  • Polar is the merchant of record
  • Sales tax and refunds handled

How a key works

  • Paste it once in Settings
  • Checked against a key in the binary
  • It never leaves your machine
  • Works with no network at all

No account required

The dashboard is already in your editor’s language.

19, shipped in the repo — not a plugin, not a paid tier, not a translation API. English is the source; the other 18 sit in files beside it.

EnglishenالعربيةarDeutschdeEspañolesFrançaisfrहिन्दीhiBahasa IndonesiaidItalianoit日本語ja한국어koNorsk bokmålnbNederlandsnlPolskiplPortuguês (Brasil)pt-BRSvenskasvไทยthTürkçetrTiếng Việtvi简体中文zh-Hans

3 ways people run this.

Same three names as the licences, in the same order, so you already know which one is yours by the time you reach the price.

  • A developer at their desk, looking up from the screen

    Post details

    astrocraft.dev/blog/

    The solo developer

    One project you maintain and also write for. You want the admin so you stop editing frontmatter in a code editor at eleven at night.

  • Three colleagues reviewing work together around a laptop

    Changes requested· back with you

    Domi Roussel asked for changes 20 minutes ago — “Excerpt still says 40k pages, should be 40,000.”

    The studio

    Client sites you built and still own. You want the client changing their own copy without a Slack message, and without touching your components.

  • Two colleagues talking over a tablet at a counter

    What a licence covers

    • A year of updates from the date on the key
    • Verified offline: no account, no licence server, no phone-home
    • Use it on as many of your own machines as you like

    The agency

    A dozen sites on one stack. You want one key, one invoice, and no per-seat arithmetic every time a junior joins.

Everything else you would ask a maintainer.

6 things the sections above leave open.

Do I need a licence for it to work?
No. An unlicensed copy is not a trial — it is the same build with a reminder in it, never watermarked and never throttled. The key is a one-time purchase covering a set number of sites: you paste it once in Settings, it is checked against a key in the binary, and it never leaves your machine.
What happens when the year of updates ends?
Nothing stops. The build you are on keeps working on the sites the key covers, for as long as you run it — the year buys new versions, not permission to use the old one. Renew when a release you actually want lands.
Can it run with no network at all?
Yes. The editor is part of your own Astro build and publishing is git commit && git push, so the only thing that ever needs a network is your git remote. There is no account, no licence server and no phone-home — the key is checked against a key in the binary, on your machine.
Does it change the pages I already have?
No. It reads the collections your content.config.ts already declares and writes back to the same markdown files. Your components, layouts and routes are untouched, and taking it out again leaves a normal Astro project behind.
The project moved, or a client took it over — now what?
The key travels with the repo. It covers sites rather than seats, so a handover is a line on an invoice and nothing to deactivate — and if the client would rather hold their own key, yours frees up for the next project.
When do the six missing things land?
They ship on the changelog with dates on them, not on a roadmap with quarters. Anything drawn on this page ships in the version it is drawn for; anything else is a request, and an issue on the repo is the fastest way to move it.

Install it into a site you already have.

Four files and one config, and your markdown stays where it is. Install it unlicensed and every feature works — the licence is what you buy when it sticks.