Installation
Medice ships as a complete Astro project, not as an npm package or an integration you register. You clone the repository, install its dependencies and start editing — there is no theme layer between you and the markup, and nothing is hidden inside node_modules. Every component, token, icon, animation and the booking validator are files in src/ that you own from the first commit.
It runs with no configuration, no API keys and no accounts. pnpm install followed by pnpm dev gives you the whole practice — the homepage, eighteen specialties, a nine-clinician directory, a ten-article health library, a fourteen-role careers board, a twenty-six question FAQ, legal pages and a six-step booking form — populated with written sample content. The booking form is the one thing that wants secrets, and without them it fails honestly rather than pretending to have sent something.
Requirements
- Node.js 22.13.0 or newer.
engines.nodeinpackage.jsonpins the floor at>=22.13.0. The floor is set by pnpm 11 rather than by the language, but the test runner also leans on Node’s--experimental-strip-types, which is how every*.test.tsundersrc/runs. Check yours withnode -v. - pnpm. The lockfile is
pnpm-lock.yamlandpnpm-workspace.yamlcarries settings only pnpm reads.corepack enable pnpmis the shortest route if you do not have it. - Git, to clone the repository and to keep your own history from the first commit onward.
You do not need a hosting account, an email provider or a domain to run the theme locally. One route — POST /api/book/ — is server-rendered, and it renders perfectly well without an email provider configured: it answers 500, logs which variable is missing, and shows the visitor a “we could not send that” notice. Everything else is a prerendered file.
Get the code
Clone the repository and drop the upstream history so your project starts with a clean log:
git clone https://github.com/Astro-Craft-Theme/medice.git my-clinic
cd my-clinic
rm -rf .git && git init
If you would rather keep the upstream remote so you can pull theme updates later, skip the rm -rf .git and rename the remote instead:
git remote rename origin upstream
git remote add origin [email protected]:you/my-clinic.git
Keeping upstream is only worth it if you plan to merge theme changes. Because the theme is source you edit directly, a merge after heavy customization is a real merge — most people take the clean-slate route and treat the clone as a starting point.
Install dependencies
pnpm install
The dependency list is deliberately short. Beyond Astro and Tailwind themselves, the runtime dependencies are @astrojs/cloudflare (the adapter for the one on-demand route), @astrojs/mdx (which renders the health library’s articles), @astrojs/sitemap, the Plus Jakarta Sans font package, and the tailwind-merge / tailwind-variants pair the UI primitives are built on. There is no SEO package, no icon package, no animation package and no component kit — each of those is source in src/ instead, which is the reason the list is short and the reason you can change any of them.
First run
pnpm dev
The dev server comes up on http://localhost:4321. Every route is available immediately, including /book/ — the form renders and validates client-side without any secrets; only the final send needs them.
Two places are worth visiting first. /examples/ui is a dev-only catalog that renders all 37 UI primitives in every variant on one page; it is noindex, excluded from the sitemap and emits no paths in a production build, so it costs you nothing until you delete it. And /book/ is the most intricate page in the theme — six steps, a derived price estimate and a summary aside — which makes it the fastest way to see the token layer, the primitives and the motion catalog all working at once.
The values to change first
Nothing below blocks local development. They are what turns the sample practice into yours.
SITE_URL— your production domain, set in your host’s environment variables. It feeds canonical URLs, OG tags, JSON-LD, the sitemap,robots.txtandllms.txtat once. A fresh clone builds on thehttps://example.complaceholder so you can see the site before owning a domain; a production deploy throws rather than ship the placeholder. Local builds and deploy previews are unaffected.src/config/siteData.json.ts— the brand name and description (the description ships in the JSON-LD on every page and opensllms.txt, so it is how crawlers learn what the practice is), the contact block,twitterCreatorand thesameAssocial URLs. A check fails the build if the description still describes a starter template.src/config/legalData.json.ts— the terms and privacy copy are placeholders. Have them reviewed; they are not legal advice.public/og.jpgand the favicons — replace the placeholder 1200×630 social image,public/favicon.svgandpublic/favicon.ico.RESEND_API_KEY,BOOKING_FROM,BOOKING_TO— only if you want the booking form to actually send. See Booking Form.
The sample content is written rather than lorem-ipsum, and it is internally consistent: the prices on the booking form come from the same price list the pricing panel draws, and a clinician’s clinic on a booking email is derived from that clinician’s roster entry. That consistency is what makes the sample useful as a reference while you replace it — but every clinician, wait time, price and headcount is invented, and the phone numbers are in the reserved fictional 555-01xx range.
Verify the install
pnpm lint && pnpm check && pnpm build && pnpm test && pnpm wiki:lint
That is the full chain, and it is the same one to run before every commit. pnpm build is the real check — content-schema and config mistakes surface there rather than at runtime. pnpm test runs every *.test.ts under src/ through Node’s type stripping, with no framework and no fixtures, and fails if it finds none, so a check cannot go missing unnoticed. See Commands for what each one covers.