micro-landing-builder
About micro-landing-builder
micro-landing-builder generates standalone, config-driven NextJS landing page apps for startups. It supports single or batch creation, with Vercel deployment and custom-domain setup only when explicitly requested.
Key features
- 01Generate standalone NextJS landing apps
- 02Configure content through app.json
- 03Build pages from CSV or JSON
- 04Set themes and landing sections
- 05Deploy to Vercel on request
Use cases
- 01Create a startup landing page
- 02Generate a group of pages from a project list
- 03Customize page content and colors in app.json
- 04Deploy landing pages with domain mapping
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ shipshitdev/ skills --skill micro-landing-builderAfter installing, type/micro-landing-builderin Claude Code to confirm it loaded.
Bundled files
References and scripts installed along with SKILL.md.
plugin.jsonassets/examples/domains.jsonprojects.csvprojects.jsonassets/templates/landing/components.jsonassets/templates/landing/app/globals.csslayout.tsxpage.tsxassets/templates/landing/app/api/subscribe/route.tsassets/templates/landing/components/sections/cta.tsxemail-capture.tsxfaq.tsxfeatures.tsxfooter.tsxheader.tsxhero.tsxpricing.tsxstats.tsxtestimonials.tsxassets/templates/landing/components/ui/accordion.tsxbadge.tsxbutton.tsxcard.tsxinput.tsxassets/templates/landing/lib/theme.tsutils.tsreferences/config-schema.mdsections-reference.mdscripts/batch_create.pydeploy_vercel.pyDetails
From the project READMEMicro Landing Builder
Create config-driven NextJS landing pages for startups.
Contract
Inputs:
- One or more landing definitions: slug, name, domain, concept, and config
- Destination root
- Slugs: one path segment of lowercase letters, digits and hyphens; anything else is rejected
- Optional domain mapping
Outputs:
- Generated landing app directories
app.jsonconfig files- Deployment plan or deployed URLs when deploy is explicitly requested
Creates/Modifies:
- Local landing app directories
- Vercel config files
- Does not deploy production by default
External Side Effects:
- May deploy to Vercel and attach custom domains only after explicit deploy request
Confirmation Required:
- Before batch creation outside the current workspace
- Before production deploys
- Before attaching custom domains
- Before overwriting an existing landing directory
Delegates To:
- Recommend
landing-page-vercelfor single static landing pages project-init-orchestrator/npx @shipshitdev/v0for full product reposdeployment-composerordeploy-appfor Vercel deployment
Concept
Each landing page is a standalone NextJS app where:
- Content is defined in
app.jsonconfig file - UI is shadcn/ui:
components.json,components/ui(Button, Card, Badge, Accordion, Input) and the landing sections incomponents/sections, all copied into the app so it owns its code - Theme tokens are shadcn CSS variables in
app/globals.css(@theme inline);app.jsonthemeoverrides--primary,--backgroundand the extra--brandaccent - Deploy independently to any domain via Vercel
Prerequisites
Nothing to publish or install first: the scaffold writes the shadcn/ui setup itself and depends only on live npm packages (Next.js 16, React 19, Tailwind v4, shadcn, radix-ui, class-variance-authority, cn, lucide-react, tw-animate-css). Versions are pinned in scripts/scaffold.py; re-check them with npm view <pkg> version before changing pins. Needs Bun and network access for bun install.
Usage
# Show help
python3 scripts/scaffold.py --help
# Create a new landing
python3 scripts/scaffold.py \
--slug mystartup \
--name "My Startup" \
--domain "mystartup.com" \
--concept "AI-powered analytics"
# Light theme (app.json theme.mode "light" with a white background and dark text)
python3 scripts/scaffold.py \
--slug mystartup \
--name "My Startup" \
--theme-mode light
# Custom colors (#rgb, #rgba, #rrggbb or #rrggbbaa); text colors are picked for contrast
python3 scripts/scaffold.py \
--slug mystartup \
--name "My Startup" \
--primary "#00ff00" \
--background "#f4f4f5"
# Allow outside current directory
python3 scripts/scaffold.py \
--root ~/www/landings \
--slug mystartup \
--allow-outside
Generated Structure
mystartup/
├── app.json # All content/config here
├── package.json # Next 16, React 19, Tailwind v4, shadcn/ui runtime deps
├── components.json # shadcn config ("config": "" for Tailwind v4)
├── next.config.ts
├── postcss.config.mjs # @tailwindcss/postcss (Tailwind v4)
├── tsconfig.json
├── vercel.json # Vercel deployment config
├── public/
│ └── (images go here)
├── lib/
│ ├── utils.ts # cn() helper
│ └── theme.ts # app.json theme -> mode and CSS variable overrides
├── components/
│ ├── ui/ # shadcn: button, card, badge, accordion, input
│ └── sections/ # header, hero, stats, features, pricing, testimonials, faq, cta, footer
└── app/
├── layout.tsx # Applies app.json theme to the shadcn CSS variables
├── page.tsx # Renders sections from app.json
├── globals.css # Tailwind v4 + shadcn tokens: :root, .dark, @theme inline
└── api/subscribe/ # Waitlist endpoint stub (returns 501 until a provider is wired)
The email capture form posts to app/api/subscribe/route.ts. It validates the address and answers 501 until you connect an email provider there, so the form never claims to have stored an email it did not.
app.json Config
The landing is entirely driven by app.json. See references/config-schema.md for full schema.
{
"name": "My Startup",
"slug": "mystartup",
"domain": "mystartup.com",
"meta": {
"title": "My Startup - Tagline",
"description": "SEO description"
},
"theme": {
"primary": "#4f46e5",
"accent": "#f59e0b",
"background": "#0a0a0a",
"foreground": "#fafafa",
"mode": "dark"
},
"analytics": {
"plausible": "mystartup.com"
},
"sections": [
{ "type": "hero", "headline": "...", "subheadline": "..." },
{ "type": "features", "items": [...] },
{ "type": "pricing", "plans": [...] },
{ "type": "faq", "items": [...] },
{ "type": "cta", "emailCapture": { "enabled": true } }
]
}
Section Types
hero- Main hero with headline, CTA buttonsstats- Key metrics/numbersfeatures- Feature grid with iconspricing- Pricing planstestimonials- Customer quotesfaq- Accordion FAQcta- Call to action with email capture
Batch Creation
Create multiple landing pages from a template or CSV/JSON file:
# From CSV file
python3 scripts/batch_create.py \
--root ~/www/landings \
--csv projects.csv \
--allow-outside
# From JSON file
python3 scripts/batch_create.py \
--root ~/www/landings \
--json projects.json \
--allow-outside
# Clone from existing template
python3 scripts/batch_create.py \
--root ~/www/landings \
--template ~/www/landings/template-landing \
--json projects.json \
--allow-outside
CSV Format
slug,name,domain,concept
project1,Project One,project1.com,AI-powered analytics
project2,Project Two,project2.com,Cloud infrastructure
Optional theme columns (headers are trimmed and case-insensitive; unknown or duplicate headers and rows with the wrong cell count abort with an error; the file may have a UTF-8 BOM): primary, accent, background, theme_mode (dark or light). Colors must be exactly #rgb, #rgba, #rrggbb or #rrggbbaa (no spaces, no empty strings in JSON; an empty CSV cell means "not set"). Invalid rows are skipped and the run exits nonzero. With --template, the colors and mode are applied to the cloned app.json, and an inherited foreground, mode and accent are cleared when a new background is given (the accent is re-derived unless you supply one).
JSON Format
[
{
"slug": "project1",
"name": "Project One",
"domain": "project1.com",
"concept": "AI-powered analytics"
},
{
"slug": "project2",
"name": "Project Two",
"domain": "project2.com",
"concept": "Cloud infrastructure"
}
]
Deployment
Single Project
Before running vercel, confirm .vercel/project.json exists in the landing directory. If it does not exist, stop and ask the user to run vercel link manually — do not run it unattended.
cd mystartup
vercel
Batch Deployment with Domains
Deploy multiple projects to Vercel with custom domains:
# Deploy with domain mapping
python3 scripts/deploy_vercel.py \
~/www/landings/project1 \
~/www/landings/project2 \
--domains-json domains.json \
--prod \
--yes
# Single domain
python3 scripts/deploy_vercel.py \
~/www/landings/project1 \
--domain project1.com \
--prod \
--yes
Domain Mapping JSON
{
"project1": "project1.com",
"project2": "project2.com"
}
Note: Domains must be configured in your DNS before adding to Vercel. Vercel will provide DNS records to add.
Workflow
Single Landing Page
- Run scaffold to create landing structure
- Edit
app.jsonwith your content - Add images to
public/ - Deploy with
vercelor usedeploy_vercel.py
Multiple Landing Pages
- Create CSV/JSON file with project definitions
- Run
batch_create.pyto generate all landing pages - Customize each
app.jsonas needed - Run
deploy_vercel.pyto deploy all with domains
Customization
Add more shadcn components with bunx --bun shadcn@latest add <name> (they land in components/ui).
To add custom sections:
- Add a component to
components/sections/ - Import it in
app/page.tsx - Register it in the
sectionComponentsmap under itstype
Change colors in app.json theme (primary, accent, background, foreground, mode). Bun validates the complete theme before scaffold or clone creation, using the same resolver as app/layout.tsx. Invalid themes fail with the failing pair and contrast ratio; choose a darker/lighter background or remove an explicit foreground. Invalid runtime edits warn and use the complete default theme. Colors accept anchored #rgb, #rgba, #rrggbb and #rrggbbaa; alpha is normalized to opaque six-digit hex with a warning. Every text pair is checked at 4.5:1, and focus indicators and input borders at 3:1, on the final rounded colors. Mode is inferred from the background unless explicitly requested; the audited surface colors work in either mode. Use the token utilities instead of hardcoded colors. See references/config-schema.md for derivation and validation details.
References
references/config-schema.md- Full JSON schemareferences/sections-reference.md- Section types and props