Build multi-page marketing websites using typed config instead of JSX.
landing-kit is an open-source, developer-first framework for creating fast, static landing websites using a structured TypeScript config.
You define pages, sections, and content as data. The framework handles routing, rendering, SEO, and static generation.
No CMS. No visual editor. No page builders. Just code → build → deploy.
landing-kit lets you build marketing websites by writing configuration, not React components.
You describe your site in two files: landing.config.ts (pages, routes, sections, meta) and main.tsx (a single component that wraps the framework content). The framework renders everything using predefined section renderers and CSS-only templates, then outputs a fully static site.
- Multi-page static website generation
- Config-driven pages and routing
- Predefined section types (hero, features, pricing, etc.)
- CSS-only templates
- Built-in SEO defaults
- Automatic sitemap.xml and robots.txt
- Optional Google Analytics (gtag)
- Static output deployable anywhere
This project intentionally does not support:
- Blogs or MDX content
- CMS or admin panels
- Drag-and-drop or visual editors
- Authentication or dashboards
- Dynamic server features
The goal is to stay opinionated and simple.
- Developers who want to ship landing pages fast
- Indie hackers and SaaS builders
- Backend-leaning devs who don’t want to write JSX for marketing pages
- Teams who prefer config + Git over visual tools
If you want full design freedom or a CMS, this is probably not for you.
- You define your site in
landing.config.ts(default export ofdefineSite(...)). - Your
main.tsxexports aMaincomponent that wraps the framework content in<LandingKit>{children}</LandingKit>. - When you run
npm run devornpm run build, thelanding-kitCLI auto-generates a hiddenapp/directory (gitignored), wires it to your config andmain.tsx, and runs Next.js. - Pages are mapped from config keys to routes; each page is rendered using predefined section renderers.
- The output is a fully static website.
Next.js is used internally, but you never see routing or page files. You only edit the config and main.tsx.
landing-kit/
├─ packages/
│ ├─ core/ # framework logic (config, rendering, section types)
│ ├─ next/ # Next.js wrapper, LandingKit component, CLI
│ ├─ templates/ # CSS-only templates
│ └─ create-landing-app/ # scaffold CLI (published as create-landing-kit)
├─ template/ # scaffold template (landing.config + main only)
└─ README.md
Your scaffolded project looks like this:
my-site/
├─ landing.config.ts # your site content (pages, sections, meta)
├─ main.tsx # your wrapper component
├─ next.config.ts # static export config (no need to edit)
├─ tsconfig.json
├─ package.json
└─ .gitignore # ignores app/, .next/, out/, node_modules
No app/ directory, no page files, no routing code. The framework handles all of that.
Scaffold a new site:
npx create-landing-kit@latest my-site
cd my-site
npm run dev
From the repo root (local development):
node packages/create-landing-app/bin.js my-site
cd my-site
npm run dev
You only edit two files:
- landing.config.ts — default export with
defineSite({ template?, meta, pages, analytics? }). Optionaltemplate:"default","micro-saas","cyberpunk", or"dev-tool". Optionalmeta.ogImage,meta.favicon. Optionalanalytics: Google Analytics measurement ID (e.g.G-XXXXXXXXXX). - main.tsx — default export
function Main({ children }) { return <LandingKit>{children}</LandingKit> }
Build static output:
npm run build
Deploy the generated out/ folder to any static host.
Place a style.css file in your project’s public/ directory to apply your own design. The framework detects it automatically and injects it in the layout. Your CSS loads after the theme, so you can override variables and add custom styles without changing any code.
Set template in landing.config.ts to one of:
- default — Core styles (blue accent, light gray backgrounds).
- micro-saas — Product-led: teal accent, soft gradients, card shadows. Suited for micro-SaaS and indie product landings.
- dev-tool — Dark, minimal, developer-focused: electric blue accent, dark surfaces, Inter typography. Suited for dev tools and technical SaaS.
- cyberpunk — Futuristic: matte black, neon cyan and magenta, glass panels, Space Grotesk + JetBrains Mono.
landing.config.ts
import { defineSite } from "@landing-kit/core";
export default defineSite({
meta: {
title: "My Product",
description: "Simple landing pages, done right",
url: "https://example.com",
// optional: ogImage, favicon
},
// optional: analytics: "G-XXXXXXXXXX"
pages: {
"/": {
title: "Home",
sections: [
{
type: "hero",
heading: "Build landing pages fast",
subheading: "Config in. Static site out.",
buttons: [
{ label: "Get started", href: "/pricing", variant: "primary" },
{ label: "Learn more", href: "/about", variant: "secondary" },
],
},
{
type: "features",
id: "features",
heading: "Why us?",
items: [
{ icon: "⚡", title: "Fast", description: "Static output. Deploy anywhere." },
],
},
],
},
},
});main.tsx
import { LandingKit } from "@landing-kit/next";
export default function Main({
children,
}: { children: React.ReactNode }): React.ReactElement {
return <LandingKit>{children}</LandingKit>;
}That’s it. Add more sections (features, pricing, cta, faq, footer) and pages in landing.config.ts as needed.
You can add optional id values to sections to enable /#hash anchors:
{
type: "features",
id: "features",
heading: "Why use landing-kit?",
items: [
// ...
],
}This lets footer links like /#features scroll to the correct section.
This project is early-stage and evolving. APIs may change until the first stable release.
Contributions, ideas, and feedback are welcome.
MIT