Skip to content

hex2null/astryx-templates

Repository files navigation

Astryx Templates

A gallery of reference applications built with the Astryx design system, React 19, TypeScript and Vite.

Each directory is a standalone project — not a workspace package. There is no root package.json; you install and run each template on its own. Copy the one closest to what you are building, or read it as a worked example of how a real Astryx page is composed.

Every template starts from the same harness (Vite + React 19 + TypeScript + oxlint + @astryxdesign/core + tdesign-icons-react) and differs only in its frame, its content and, in five cases, a custom theme.

Live demos: astryx-templates.pages.dev — every template, built and served under one directory (/dashboard/, /chat-app/, …). That page also introduces the astryx agent skill, which teaches a coding agent the procedure these templates were built with; install it with npx skills add hex2null/astryx.

Gallery

Meridian — a commerce operations console
dashboard · Meridian
Console / back-office
Nova — an AI assistant with conversation history
chat-app · Nova
Messaging
Relay — a sprint board of issue cards
kanban · Relay
Tracker (board)
Dispatch — a three-pane mail client
inbox · Dispatch
Tracker (master–detail)
Astryx Social — a timeline with a composer and discover rail
social-feed · Astryx Social
Feed
Aperture — a community image library
image-hub · Aperture
Media library
Voltyx — a consumer electronics storefront
tech-store · Voltyx
Storefront
Kite — a landing page built on a tile mosaic
bento-grid · Kite
Landing page
Meridian Vantage Partners — a consulting firm homepage
consulting · Meridian Vantage
Marketing
Broadsheet — an editorial front page
magazine · Broadsheet
Editorial
A personal résumé page with a print stylesheet
resume · Rowan Alcántara
Document
Astryx Docs — side nav, article body and outline
docs-site · Astryx Docs
Docs

Every shot is the template's own dev server at a 1485×850 viewport on a retina scale factor, in light mode — see Screenshots for how to replace one.

Quick start

Requires Node.js ^20.19.0 or >=22.12.0 (Vite 8).

git clone https://github.com/hex2null/astryx-templates.git
cd astryx-templates/dashboard   # or any other template

npm install
npm run dev      # dev server on http://localhost:5173
npm run build    # tsc -b && vite build
npm run lint     # oxlint
npm run preview  # serve the production build

Templates

Template What it is Archetype / frame Theme
dashboard Meridian — a commerce operations console: KPI tiles, chart panels (Recharts) and a dense orders table Console / back-office. AppShell + TopNav + collapsible 256px SideNav over a Layout neutral
chat-app Nova — a ChatGPT-style AI assistant with conversation history and a docked composer Messaging. AppShell + resizable SideNav over ChatLayout neutral
kanban Relay — a sprint board of draggable issue cards in five status columns Tracker (board). AppShell + TopNav + SideNav 260; LayoutContent scrolls horizontally over fixed 304px columns, each its own Layout neutral
inbox Dispatch — a three-pane mail client: mailboxes, thread list, reading pane Tracker (master–detail). AppShell + SideNav 260 + Layout with a 400px start LayoutPanel neutral
social-feed Astryx Social — an x.com-style timeline with a composer and a discover rail Feed (column frame). AppShell + SideNav | timeline 600 | rail 350, each with its own scroll custom (x-blue)
image-hub Aperture — a community image library; clicking a tile opens the photo detail view with comments Media library / gallery. AppShell + TopNav (identity, search, upload) custom (aperture)
tech-store Voltyx — a consumer electronics storefront: category and product tiles, value props, promo band Storefront (marketing + gallery). AppShell + TopNav, centred 1200 column of full-bleed bands neutral
bento-grid A product landing page whose centrepiece is a mixed-size tile mosaic Landing page. AppShell height="auto" + TopNav, full-bleed bands over a 1200 column; six-column Grid with uniform rows and GridSpan tiles neutral
consulting Meridian Vantage Partners — the homepage of a global management consulting firm Marketing / document site, single scroll of composed bands custom (meridian)
magazine An editorial front page — lead story, front section, opinion, long read and a wire column Editorial document. AppShell height="auto" + TopNav folio; twelve-column grid split differently in every band custom (press)
resume A personal résumé / CV page, with a real print stylesheet Document / profile. AppShell height="auto" + TopNav identity band, centred 1120 column custom (ink)
docs-site Documentation site — side nav, article body and a right-hand outline Docs. AppShell + Layout with LayoutPanel outline neutral

All twelve build and run. Every template except dashboard and tech-store has its own README.md with layout notes; those two still carry the default Vite boilerplate README. In all twelve the authoritative frame contract is the comment at the top of src/App.tsx (or, in consulting and magazine, the band components it composes).

Anatomy of a template

<template>/
  index.html            page title + #root + /src/main.tsx
  vite.config.ts        vite + @vitejs/plugin-react
  tsconfig*.json        app / node project references
  .oxlintrc.json        react + typescript + oxc rules
  .claude/CLAUDE.md     Astryx agent guidance (identical in every template)
  public/favicon.svg
  src/
    main.tsx            reset.css/astryx.css load order, <Theme>, registerIcons()
    index.css           @import of Astryx reset + astryx.css + the theme's CSS
    App.tsx             the page — opens with a frame contract comment
    data.ts             seed content, kept out of the layout code
    icons.tsx           thin wrapper over Astryx <Icon> with tdesign glyphs
    iconType.ts         bridges tdesign icon types onto Astryx's SVGProps slots
    theme.ts            custom theme source (only in themed templates)

src/App.tsx (or, in consulting, the band components it composes) begins with a comment that states the archetype, the frame, the container choices and the responsive behaviour before any code. That contract is the point of these templates: the frame is decided first, then content is fitted to it.

Theming

Five templates ship a custom theme — consulting (meridian), image-hub (aperture), magazine (press), resume (ink) and social-feed (x-blue). The workflow is source → generated:

# src/theme.ts is the source of truth
npx astryx theme build src/theme.ts
# → src/<name>.js, <name>.css, <name>.d.ts, <name>.variants.d.ts  (generated — do not edit)

src/index.css imports the generated <name>.css, and src/main.tsx wraps the app:

import { Theme } from '@astryxdesign/core/theme'
import { inkTheme } from './ink'   // the generated module, not theme.ts

<Theme theme={inkTheme}><App /></Theme>

Themes extend neutralTheme and adjust accents, neutral temperature and a small number of component variants — brand colour is set through defineTheme, never by overriding --color-* in :root. The unthemed templates import @astryxdesign/theme-neutral/theme.css directly instead.

Icons

Icons come from tdesign-icons-react. main.tsx calls registerIcons() to map Astryx's semantic icon slots (close, chevronDown, search, …) onto tdesign glyphs, so built-in components render correctly. For icons used directly in the page, go through the local Icon wrapper in src/icons.tsx to keep Astryx's semantic size/color props.

Conventions

The rules the templates follow are documented in each project's .claude/CLAUDE.md (identical everywhere) and enforced by review, not by tooling. In short:

  • No raw <div> — Astryx components do all layout and spacing.
  • Frame first — pick the shell (AppShell, or Layout + LayoutPanel) and budget regions in px before writing content.
  • Rows for dense data (Table, List/Item), edge to edge. Card is for dashboard widgets, galleries and settings groups — never one card per list row.
  • Tokens for every valuevar(--color-*), var(--spacing-*), var(--radius-*). No raw hex or px, no utility-class CSS, no hand-written stylesheets except where a platform feature has no component API (e.g. the print rules in resume/src/index.css).

The Astryx CLI is the discovery tool — run it from inside a template:

npx astryx build "<idea>"      # returns a kit: closest page + blocks + components
npx astryx template <name>     # scaffold or study a page/block recipe
npx astryx component <Name>    # props + examples
npx astryx search "<query>"    # find a component, hook, doc or template
npx astryx docs <topic>        # layout, tokens, color, spacing, typography, motion, …
npx astryx upgrade --apply     # run after bumping @astryxdesign/core

Screenshots

screenshot/<template>.webp is a 1200×675 image used by the README gallery above and by the demo site's cards. These twelve files are the only images the repository keeps: the full-resolution captures they were cut from are throwaway and deliberately not committed, so cloning stays cheap and the site build only ever copies bytes.

To replace one, capture the page, then convert it:

./screenshot/build-thumbs.sh resume ~/Desktop/shot.png

That script needs ImageMagick (brew install imagemagick); nothing else in the repo does. It crops to a uniform 16:9 anchored at the top, because GitHub's markdown has no object-fit and the README relies on the files themselves being the same shape. Since the source is not kept, changing the crop or the size means recapturing every template — worth knowing before you touch those numbers.

Capture from the template's own dev server at a 1485×850 viewport, device pixel ratio 2, light mode, which is what makes the set look like one gallery rather than twelve unrelated images, and lands almost exactly on the 16:9 crop. Three things to check before committing a new one:

  • Recapture after changing the page. A screenshot is a copy of the source at one moment and nothing enforces that it stays current — kanban's first capture was taken minutes before kanban/src/dates.ts pinned its formatter, so it shipped 2026年7月29日 on a zh-CN machine while the code it depicted already read 29 Jul.
  • Every date and number formatter is locale-pinned (en-GB in inbox and kanban, en-US in dashboard and tech-store), so a capture reads the same on any machine. If you add a bare toLocaleDateString() or new Intl.DateTimeFormat(undefined, …), that stops being true — the shot then follows whatever locale the capturing browser happens to use.
  • Wait for images. The gallery cards are loading="lazy"; a full-page screenshot taken too early shows empty slots that are not actually broken.

Deploying the demo site

All twelve templates are published together as one Cloudflare Pages site, each mounted on its own path. deploy/build-site.mjs builds every template with --base=/<name>/ straight into site/<name>/ — Vite rewrites the bundle, favicon and public/ URLs with that base, so each app works unchanged from a subdirectory. The landing page at site/index.html and the site/404.html beside it are generated from the same script — markup, stylesheet and all — so the site has no build step of its own and no framework behind it.

The landing page leads with the astryx agent skill, not with the grid: the demos are what the skill produces, so the page shows the procedure first and the evidence second. Its hero is a console running one /astryx build to completion, printing the frame as a box diagram with real region budgets before it names a file — the skill's own argument, made in the skill's own vernacular. Below that come the usage examples, then the demo grid, then Astryx itself.

That page is hand-written HTML and CSS inside build-site.mjs, deliberately not an Astryx app — it is the wrapper around the templates, not one of them, so the conventions above do not apply to it. It ships one small inline script, for the install command's copy button. The console keeps its own dark palette in both colour schemes; everything else follows prefers-color-scheme.

The demo grid is generated from the template list in that script, so the landing page can never advertise a demo that was not built. Each card carries the template's screenshot, copied from screenshot/ into site/screenshot/; a template with no image still builds, its card simply renders without one and the missing name is reported at the end of the run.

node deploy/build-site.mjs             # build all twelve into ./site
node deploy/build-site.mjs dashboard   # rebuild one (gallery is regenerated either way)

npx wrangler pages deploy site --project-name astryx-templates

site/ is generated and git-ignored. There is still no root package.json — the script shells out to each template's own local tsc and vite, and installs its dependencies first if node_modules is missing. None of the templates use a router, so no SPA fallback or _redirects file is needed; Pages resolves /<name>/ to /<name>/index.html on its own.

To deploy from CI instead, point a Cloudflare Pages Git integration at this repo with build command node deploy/build-site.mjs and output directory site.

Adding a template

  1. Copy the closest existing template into a new top-level directory.
  2. Update index.html (<title>), src/data.ts and src/App.tsx; keep the frame contract comment at the top of App.tsx current.
  3. Replace the boilerplate README.md with a description of the template and its frame.
  4. Add an entry to TEMPLATES in deploy/build-site.mjs so it ships with the demo site.
  5. Capture the page per Screenshots, run ./screenshot/build-thumbs.sh <name> <capture.png>, and add a cell to the README gallery.
  6. Verify npm run build and npm run lint pass before opening a pull request.

License

MIT — use these templates as the starting point for anything, commercial work included. @astryxdesign/*, react and the other dependencies keep their own licenses.

About

A gallery of reference applications built with the Astryx design system

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages