A component library for modern B2B SaaS landing pages, built with React, Next.js, and Tailwind CSS.
Ship professional landing pages in hours, not weeks. While other libraries offer generic UI components, Lantern UI provides complete, conversion-optimized sections specifically designed for B2B SaaS - from hero sections that convert to pricing tables that sell.
Following the shadcn/ui philosophy, copy components directly into your project for full control and customization.
Visit lanternui.com to browse components, view live previews, and copy source code with one click.
- Node.js 22.0+
- pnpm 10.0+
- Typescript
- React 19.0+
- React DOM 19.0+
- Tailwind CSS 4.0+
- Next.js 15.0+
- shadcn 3.0+
For the fastest setup, use our template which comes pre-configured with all of the above, and support for easy deployment to Cloudflare Pages or via Lantern.
git clone https://github.com/dqii/next-cf-template my-app
cd my-app
pnpm installThen follow the installation instructions below to add Lantern UI components.
Configure Lantern UI as a namespaced registry in your components.json:
{
"registries": {
"@lantern": "https://lanternui.com/r/{name}.json"
}
}Then install components using the namespace:
# Install a single component
npx shadcn@latest add @lantern/hero-03
# Install multiple components
npx shadcn@latest add @lantern/hero-03 @lantern/footer-01 @lantern/cta-01The CLI will automatically resolve all Lantern UI dependencies (e.g., @lantern/typography, @lantern/button) from the Lantern registry, and any shadcn UI dependencies (e.g., input, select) from the default shadcn registry.
Browse and copy component source code directly from lanternui.com into your project for full control and customization.
Build complete marketing pages by composing section components.
Pick the section components you want on your page and install it:
npx shadcn@latest add @lantern/hero-54 @lantern/logos-00 @lantern/code-01 @lantern/contact-01Each section is self-contained and customizable:
import { Hero54 } from "@/components/section/hero-54";
import { Logos } from "@/components/section/logos-00";
import { Code01 } from "@/components/section/code-01";
import { Contact } from "@/components/section/contact-01";
export default function LandingPage() {
return (
<>
<Hero54
title="Your compelling headline"
subtitle="Supporting text that converts"
primaryButtonText="Get Started"
primaryButtonHref="/signup"
/>
<Logos
title="Trusted by industry leaders"
logos={[{ name: "Company", href: "/logo.png" }]}
/>
<Code01
title="Simple integration"
codeItems={[{ id: "example", label: "Example", code: "..." }]}
/>
<Contact title="Get in touch" fields={[...]} />
</>
);
}Create dynamic blogs and documentation sites with MDX/Markdown files and frontmatter support.
1. Install the required components:
npx shadcn@latest add @lantern/article-page @lantern/articles-page @lantern/article-contentPick any article-list-* variant and article-layout-* variant and install those as well:
npx shadcn@latest add @lantern/article-layout-01 @lantern/article-list-082. Set up your content structure:
content/
├── authors.json # Author definitions (optional)
└── blog/ # Your blog posts
├── my-first-post.mdx
└── another-post.md
3. Define authors (optional):
Create content/authors.json to centralize author information:
{
"authors": {
"sarah-johnson": {
"id": "sarah-johnson",
"name": "Sarah Johnson",
"role": "Head of Product",
"avatar": "/avatars/sarah.jpg",
"bio": "Sarah leads product strategy..."
}
}
}4. Write content with frontmatter:
---
title: "Building Scalable Web Applications"
subtitle: "A guide to modern development practices"
date: "2024-03-15"
authors: ["sarah-johnson"] # Reference author IDs
tags: ["engineering", "architecture"]
---
## Introduction
Your markdown content starts here. Note that you should start
with H2 (##) since the title is rendered from frontmatter.If you don't use authors.json, you can still embed author data directly (both shapes are supported):
---
authors:
- name: "Sarah Johnson"
avatar: "/avatars/sarah.jpg"
---5. Create your article page route:
// app/blog/[slug]/page.tsx
import { ArticleLayout } from "@/components/content/article-layout-01";
import {
ArticlePage,
generateArticleMetadata,
generateArticleStaticParams,
} from "@/components/content/article-page";
// Generate static params for all articles
export async function generateStaticParams() {
return generateArticleStaticParams("blog");
}
// Generate metadata for SEO
export async function generateMetadata({
params,
}: {
params: { slug: string };
}) {
return generateArticleMetadata(params.slug, "blog");
}
// Render the article
export default function BlogPostPage({ params }: { params: { slug: string } }) {
return (
<ArticlePage
slug={params.slug}
contentDirectory="blog" // Local folder under content/
collectionName="Blog" // Display name
collectionPath="/blog" // URL path
ArticleLayout={ArticleLayout}
/>
);
}6. Create a blog listing page (ArticlesPage):
// app/blog/page.tsx
import { ArticleList as ArticleList08 } from "@/components/content/article-list-08";
import { ArticlesPage } from "@/components/content/articles-page";
export default function BlogPage() {
return (
<ArticlesPage
title="Blog"
subtitle="Insights, tutorials, and product updates."
contentDirectory="blog"
ArticleListComponent={ArticleList08}
/>
);
}Note: @/lib/content uses Node fs; pages calling these helpers must run in the Node runtime (not Edge).
If you prefer a single page component that handles layout and data fetching, use ArticlesPage and pass any article-list-* variant as the renderer:
// app/blog/page.tsx
import { ArticleList as ArticleList08 } from "@/components/content/article-list-08";
import { ArticlesPage } from "@/components/content/articles-page";
export default function BlogPage() {
return (
<ArticlesPage
title="Blog"
subtitle="Insights, tutorials, and product updates."
contentDirectory="blog"
ArticleListComponent={ArticleList08}
/>
);
}Notes:
- This component runs on the Node runtime because it calls
@/lib/content(usesfs). - You can swap
ArticleListComponentto any design variant.
- Content helpers use Node's
fsto read Markdown/MDX andcontent/authors.json. Pages or routes that call these helpers must run on the Node.js runtime (not Edge). - Import shared types and helpers from
@/lib/contentin your app code:
import type { Article, ArticleListItem, Author } from "@/lib/content";Machine-readable JSON endpoints for automated tools and LLMs:
/r/categories.json- Contains a hierarchical tree of all component categories and subcategories with their descriptions and component counts for each section./r/component-listings.json- Provides a complete listing of all components with their IDs, titles, and descriptions organized by category and subcategory./r/component-listings-{category}.json- Lists all components within a specific category, including subcategory information where applicable./r/component-listings-{category}-{subcategory}.json- Individual files for each subcategory containing just that subcategory's components with their metadata.
Want to contribute? Check out our Contributing Guide for development setup and guidelines.
- Add Blog tab
- Add "Introducing Lantern UI Components"
- Add "Introducing Lantern UI Palettes"
- Add "Best Practices for Using Lantern UI"
- Add Docs tab -- this should explain how to get started
- Additional sections: Features (Bullets), News Articles, Case Studies, Team, Navbar, Changelog
MIT License