Uniweb
For developers

Content and code are separate. They meet when a page renders.

A Uniweb project has two parts. The site is content. The foundation is React. A thin runtime joins them wherever a page renders: in a build, on the host and in the browser. This page shows what that looks like in a real project, whether you work with an agent or on your own, on your sites or your clients’.

ReactViteTailwind v4Apache 2.0
01

Markdown in. A typed object out.

Authors write a section as a Markdown file. Before any component sees it, the file is parsed into an object with named fields: strings and arrays, never null. Headings mark structure, not size.

site/pages/home/hero.md
---
type: Hero
theme: dark
---
# Ship the site this week
## Not every change needs a developer

We help small teams publish.

[Get started](/start)
what the component receives
content = {
  title: 'Ship the site this week',
  subtitle: 'Not every change needs…',
  paragraphs: ['We help small teams…'],
  links: [{ label: 'Get started', … }],
  items: [],
  // images, icons, data, …
}

$ uniweb inspect pages/home/hero.md

src/sections/Hero/index.jsx
import { H1, H2, P } from '@uniweb/kit'

export default function Hero({ content }) {
  return (
    <>
      <H1 text={content.title} />
      <H2 text={content.subtitle} />
      <P text={content.paragraphs} />
    </>
  )
}

That is the whole component. It has no wrapper element, no null checks, no theme logic and no hardcoded strings.

02

Thin section types. Ordinary React behind them.

A section type is the part authors can name. It reads the params, picks a component and passes plain props. Everything behind it is ordinary React: any package, any library, any pattern.

One type for the author, as many renderings as the design needs.

src/sections/Hero/index.jsx
const workers = { slider: SliderHero, contact: ContactHero }

export default function Hero({ content, params, block }) {
  const Worker = workers[params.variant] || SliderHero
  return (
    <Worker
      title={content.title}
      links={content.links}
      images={content.images}
      block={block}
    />
  )
}
03

meta.js is the interface.

Each section type declares what it reads and which params it accepts. That one file sets the defaults, builds the controls in the visual editor and tells an agent what exists.

Every param you declare is something an author can change without you.

src/sections/Features/meta.js
export default {
  title: 'Feature Grid',
  content: {
    title: 'Heading',
    items: { label: 'Cards [3-6]' },
  },
  params: {
    columns: { type: 'number', default: 3 },
    variant: {
      type: 'select',
      options: ['default', 'centered'],
      default: 'default',
    },
  },
}
04

The runtime does these once, for every section.

What is left for you to write is rendering logic.

Section wrapping and backgrounds. Set in frontmatter, painted by the runtime.
Theming. Tokens adapt to each section’s light or dark context. The site owns the colors and fonts.
Routing and links. Link to a page by id and the link survives when the page moves.
Data. Name a query and declare its key in meta.js: the records arrive in content.data, prerendered. No fetch in an effect.
Languages. Content arrives already translated. There are no string keys in your components.
Prerendering. In the build for static hosts, just in time at the edge on Uniweb Cloud.
Search and AI indexes. A search index, an llms.txt and a Markdown copy of every page, from the same content.
05

A normal project, in two packages.

The site and the foundation are separate packages in one workspace. Install any library in the foundation as you would in any React project. The CLI owns the build configuration.

One foundation can serve many sites.

project layout
site/the contentpages/one Markdown file per sectionrecords/one file per record, by schemaqueries.ymlnamed queries over recordslocales/translationstheme.ymlcolors and fontssite.ymlpages, languages, servicessrc/the foundationsections/section types authors can usecomponents/ordinary Reactlayouts/custom layoutsmain.jsfoundation settingsstyles.cssTailwind and theme tokens
Step 1

Create

A project from a template, with its manual for agents.

$ npx uniweb@latest create my-site --template marketing
Step 2

Run

The dev server prints its address, and the page updates as you save.

$ cd my-site && pnpm install && pnpm dev
Step 3

Check

See what a section file parses to, before anything renders.

$ npx uniweb inspect site/pages/home/hero.md
Step 4

Publish

Live on Uniweb hosting, and in the visual editor for anyone you work with.

$ npx uniweb publish
06

With an agent, or on your own.

Most developers now work with an agent, and Uniweb is made for it, but nothing in it requires one. The project is ordinary files, and the manual every project carries reads as well for a person as for an agent.

AGENTS.mdThe project’s manual: how the framework works, where habits from other frameworks mislead, and how to check your work.
uniweb guideThe rest of the manual, one subject at a time, for the version you run.
uniweb.io/docsGuides and reference, with an index for agents at llms.txt.
07

Commands that tell you the truth.

You and your agent use the same ones. Nothing has to be guessed: the directory listing is the catalog, and inspect prints what a file parsed to.

uniweb createStart a project from a template.
uniweb devServe the site locally with live reload.
uniweb inspectPrint the parsed shape of a file or a page.
uniweb doctorCheck the project configuration.
uniweb validateCheck records against their schemas.
uniweb guideRead the manual for the version you run.
uniweb push / pullSync with the visual editor. Authors’ edits come back as a commit.
uniweb publishGo live on Uniweb Cloud.
uniweb deployShip to a static host, such as Cloudflare Pages or Netlify.
08

From a site to an app.

The same project grows past pages. Records are served live, services turn on with a line in site.yml, and a site can have its own backend, with accounts and payments. None of it needs a rewrite: the same foundation works on a site with these services and on one without them.

Records. One file per record in records/<schema>/, asked for by name in queries.yml. Served live on Uniweb hosting, compiled into the build on a static host, and edited in the visual editor as forms.
Services. Search, forms, statistics and an assistant, each a line under services: in site.yml.
Its own backend. Sign-in, roles and what each member creates, through @uniweb/api and the site’s backend service, with a mock backend for uniweb dev.
Payments. Through the site owner’s own Stripe account, built into the backend.
09

Your sites, or your clients’.

Uniweb fits both ways of working.

Your own sites

Files, the app, or both

Keep the content in your files and Git, bring the site into the visual editor, or work in both, and publish when it’s ready.

$ uniweb publish
Your clients’ sites

Your foundation, their sites

Register the foundation, and clients compose their sites in the visual editor from your section types, with the options you gave them. You keep improving it and release new versions.

$ uniweb register
10

Two ways to ship.

We recommend Uniweb Cloud from a site’s first pages. A simple site costs the least there, because each service is priced on its own; every publish keeps the site in the visual editor, ready to edit; and the site grows into everything a Uniweb site can do with no changes. A static host is free, and serves what a build makes.

Recommended · paid

Uniweb Cloud

Pages prerendered just in time at the edge, over live data. The site in the visual editor on every publish. Live records, forms, analytics, accounts and payments when you need them.

$ uniweb publishSee prices
Free · no account

Any static host

Deploy in one command to Cloudflare Pages, GitHub Pages, Netlify, Vercel or S3 with CloudFront, or export a folder for any other host. Edits from the app reach it through a new build, and live content, forms, analytics and accounts need services of your own.

$ uniweb deploy --host=cloudflare-pages

Start a project.

$ npm create uniweb

Or hand it to your agent. Every project comes with an AGENTS.md that tells it how the framework works and how to check its own work.