Skip to content
AstroCraft Docs
On this theme

Installation

Urbic 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 CMS itself are files in src/ that you own from the first commit.

What makes Urbic different from a static theme is the second half of it: an embedded, git-backed CMS at /admin/. It is not a hosted service and not a plugin calling home — it is source in src/admin/, it reads your Zod schemas, and every edit it makes lands in your repository as a real commit. The operator manual for that CMS lives at editor.astrocraftthemes.com/docs; these pages cover how Urbic mounts it and what it is wired to. Start with The CMS once the site is running.

Requirements

  • Node.js 22.13.0 or newer. engines.node in package.json pins 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.ts under src/ runs. Check yours with node -v.
  • pnpm. The lockfile is pnpm-lock.yaml and pnpm-workspace.yaml carries settings only pnpm reads. corepack enable is the shortest route if you do not have it — it reads packageManager from package.json and pins the right version.
  • Git, and not only to clone. The CMS commits and pushes through it, so git is a runtime dependency of the deployed container as well as a development one.

You do not need a hosting account, an email provider, a database or a domain to run the theme locally. Two things want secrets and both fail honestly without them: the enquiry form at /contact/ reports that it is not configured, and Publish in the CMS refuses until a licence is activated. Everything else — every page, the whole admin, sign-in, editing, saving, committing — runs on a fresh clone with nothing set.

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/urbic.git my-studio
cd my-studio
rm -rf .git && git init && git add -A && git commit -m "Initial commit"

That last commit is not housekeeping. The CMS reads git state on every screen and refuses to sync a dirty tree, so a checkout with no commits at all is one the admin cannot describe. Make one before you sign in.

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

Twenty-one runtime dependencies, and the split is worth knowing before you prune any of them. Astro, Tailwind, sharp, tailwind-merge, tailwind-variants, the two Fontsource families and lenis are the site’s. db0, @libsql/client, unstorage, @noble/hashes, unified, the three remark-* packages and yaml arrive with the CMS and leave with it. @astrojs/node, @astrojs/mdx and @astrojs/sitemap are shared. 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, the admin included.

Three places are worth visiting first. / is the studio homepage — eight bands that show the token layer, the motion catalog and the scroll-driven work all at once. /examples/ui is a dev-only catalog that renders all 45 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 /admin/ is the CMS: create the first account at /admin/signup/, which becomes the owner. See Your first account for what that account can do and how to invite the rest of a team.

The values to change first

Nothing below blocks local development. They are what turns the sample studio into yours.

  1. SITE_URL — your production domain, set in your host’s environment variables. It feeds canonical URLs, OG tags, JSON-LD, the sitemap, robots.txt and llms.txt at once — six things one wrong value poisons together, none of them visibly broken in review. A fresh clone builds on the https://example.com placeholder 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. See .env.example.
  2. src/config/siteData.json.ts — the brand name and description (the description ships in the JSON-LD on every page and opens llms.txt), the author block, the sameAs social URLs that disambiguate the JSON-LD Organization, and the four contact values. Phone, email, address and hours there are the mock’s invented Copenhagen studio, and they are read by the header panel, the footer identity row and the contact page at once.
  3. src/config/legalData.json.ts — the terms and privacy copy are placeholders. Have them reviewed; they are not legal advice.
  4. public/og.jpg and the favicons — replace the placeholder 1200×630 social image, public/favicon.svg and public/favicon.ico.
  5. RESEND_API_KEY and CONTACT_TO_EMAIL — only if you want the enquiry form to actually deliver. See Contact Form.
  6. A licence key, if you intend to publish from the CMS rather than from a terminal. Everything else in the admin works without one. See Publishing.

The sample content is written rather than lorem-ipsum, and it is internally consistent — a project’s order fixes both its slot in the /work/ grid and its neighbours in the detail pager, and the homepage’s project band hand-picks six of the same nine case studies the archive lists. That consistency is what makes the sample useful as a reference while you replace it, but every project, client, address and phone number in it is invented.

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/ (135 of them) through Node’s type stripping, with no framework and no fixtures, and fails if it finds none, so a check cannot go missing unnoticed. pnpm wiki:lint does the same job for the repo’s wiki/: it resolves every path:line citation and checks the cited line still contains the symbol the prose names. See Commands for what each one covers.

There is a second suite, pnpm test:cms, which runs the admin’s Vitest specs under happy-dom. It is separate because those tests need a DOM and a synced content store; pnpm test deliberately needs neither.

NEXT STEPProject Structure