diff --git a/apps/web/src/app/(home)/_components/navbar.tsx b/apps/web/src/app/(home)/_components/navbar.tsx
index f75df39..6b86eef 100644
--- a/apps/web/src/app/(home)/_components/navbar.tsx
+++ b/apps/web/src/app/(home)/_components/navbar.tsx
@@ -47,6 +47,7 @@ export default function Navbar() {
label: "Demo",
target: "_blank",
},
+ { href: "/showcase", label: "Showcase" },
{ href: "/docs", label: "Docs" },
{
href: "https://www.npmjs.com/package/create-better-t-stack",
@@ -67,6 +68,7 @@ export default function Navbar() {
label: "Demo",
target: "_blank",
},
+ { href: "/showcase", label: "Showcase" },
{ href: "/docs", label: "Docs" },
{
href: "https://www.npmjs.com/package/create-better-t-stack",
diff --git a/apps/web/src/app/(home)/page.tsx b/apps/web/src/app/(home)/page.tsx
index 3d9c4f4..715ae86 100644
--- a/apps/web/src/app/(home)/page.tsx
+++ b/apps/web/src/app/(home)/page.tsx
@@ -1,14 +1,13 @@
"use client";
import { Button } from "@/components/ui/button";
import { TECH_OPTIONS } from "@/lib/constant";
-import { Github, Star } from "lucide-react";
-import { motion } from "motion/react";
+import { Github, Star, Terminal } from "lucide-react";
import Link from "next/link";
import { useEffect, useState } from "react";
-import FeatureCard from "./_components/FeatureCard";
import CodeContainer from "./_components/code-container";
import Footer from "./_components/footer";
import Navbar from "./_components/navbar";
+import NpmPackage from "./_components/npm-package";
import SponsorsSection from "./_components/sponsors-section";
import Testimonials from "./_components/testimonials";
@@ -37,191 +36,200 @@ export default function HomePage() {
fetchStars();
}, []);
- const containerVariants = {
- hidden: { opacity: 0 },
- visible: {
- opacity: 1,
- transition: {
- staggerChildren: 0.15,
- },
- },
- };
-
- const itemVariants = {
- hidden: { opacity: 0, y: 20 },
- visible: {
- opacity: 1,
- y: 0,
- transition: {
- duration: 0.5,
- ease: "easeOut",
- },
- },
- };
-
- const sectionVariants = {
- hidden: { opacity: 0, y: 30 },
- visible: {
- opacity: 1,
- y: 0,
- transition: {
- duration: 0.6,
- ease: "easeOut",
- },
- },
- };
-
- const webFrontendOptions = TECH_OPTIONS.webFrontend.filter(
- (option) => option.id !== "none",
- );
- const nativeFrontendOptions = TECH_OPTIONS.nativeFrontend.filter(
- (option) => option.id !== "none",
- );
- const combinedFrontendOptions = [
- ...webFrontendOptions,
- ...nativeFrontendOptions,
+ const frontendOptions = [
+ ...TECH_OPTIONS.webFrontend.filter((option) => option.id !== "none"),
+ ...TECH_OPTIONS.nativeFrontend.filter((option) => option.id !== "none"),
];
const backendOptions = TECH_OPTIONS.backend.filter(
(option) => option.id !== "none",
);
- const runtimeOptions = TECH_OPTIONS.runtime.filter(
- (option) => option.id !== "none",
- );
- const apiLayerOptions = TECH_OPTIONS.api.filter(
- (option) => option.id !== "none",
- );
const databaseOptions = TECH_OPTIONS.database.filter(
(option) => option.id !== "none",
);
+ const runtimeOptions = TECH_OPTIONS.runtime;
+ const packageManagerOptions = TECH_OPTIONS.packageManager;
+ const apiOptions = TECH_OPTIONS.api.filter((option) => option.id !== "none");
const ormOptions = TECH_OPTIONS.orm.filter((option) => option.id !== "none");
const dbSetupOptions = TECH_OPTIONS.dbSetup.filter(
(option) => option.id !== "none",
);
- const addonsOptions = TECH_OPTIONS.addons.filter(
- (option) => option.id !== "none",
- );
- const examplesOptions = TECH_OPTIONS.examples.filter(
- (option) => option.id !== "none",
+ const authOptions = TECH_OPTIONS.auth.filter(
+ (option) => option.id !== "false",
);
+ const addonsOptions = TECH_OPTIONS.addons;
+ const examplesOptions = TECH_OPTIONS.examples;
+
+ const techStackCategories = [
+ {
+ category: "Frontend Frameworks",
+ options: frontendOptions,
+ },
+ {
+ category: "Backend Frameworks",
+ options: backendOptions,
+ },
+ {
+ category: "Database Systems",
+ options: databaseOptions,
+ },
+ {
+ category: "Runtime Environments",
+ options: runtimeOptions,
+ },
+ {
+ category: "API Layers",
+ options: apiOptions,
+ },
+ {
+ category: "ORM Solutions",
+ options: ormOptions,
+ },
+ {
+ category: "Database Setup",
+ options: dbSetupOptions,
+ },
+ {
+ category: "Authentication",
+ options: authOptions,
+ },
+ {
+ category: "Package Managers",
+ description: "Dependency management tools",
+ options: packageManagerOptions,
+ },
+ {
+ category: "Development Tools",
+ options: addonsOptions,
+ },
+ {
+ category: "Example Projects",
+ options: examplesOptions,
+ },
+ ];
return (
<>
-
-
-
-
-
-
- Roll Your Own Stack
-
-
+
+
+
+
+
+
+
+
+ CLI Tool for Developers
+
+
+
-
+
+ Roll Your Own
+
+ Stack
+
+
+
A modern CLI tool for scaffolding end-to-end type-safe
TypeScript projects with best practices and customizable
configurations.
-
+
-
-
-
-
-
-
-
- {/* */}
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
-
-
+
+
+
+
+ Tech Stack Options
+
+
+ Choose from modern, production-ready technologies
+
+
-
-
-
+
+
+
+
+ |
+ Category
+ |
+
+ Options
+ |
+
+
+
+ {techStackCategories.map((category) => (
+
+ |
+ {category.category}
+ |
+
+
+ {category.options.map((option) => (
+
+ {option.icon && (
+ 
+ )}
+ {option.name}
+
+ ))}
+
+ |
+
+ ))}
+
+
+
+
+
+
+
>
diff --git a/apps/web/src/app/global.css b/apps/web/src/app/global.css
index 3de5ca4..2f7d753 100644
--- a/apps/web/src/app/global.css
+++ b/apps/web/src/app/global.css
@@ -147,38 +147,38 @@
:root {
--radius: 0.35rem;
/* --background: oklch(0.96 0.01 264.53); */
- --background: oklch(1.0 0 0);
+ --background: oklch(1 0 0);
--foreground: oklch(0.44 0.04 279.33);
- --card: oklch(1.0 0 0);
+ --card: oklch(1 0 0);
--card-foreground: oklch(0.44 0.04 279.33);
--popover: oklch(0.86 0.01 268.48);
--popover-foreground: oklch(0.44 0.04 279.33);
- --primary: oklch(0.55 0.25 297.02);
- --primary-foreground: oklch(1.0 0 0);
+ --primary: oklch(0.5 0.18 297.02);
+ --primary-foreground: oklch(1 0 0);
--secondary: oklch(0.86 0.01 268.48);
--secondary-foreground: oklch(0.44 0.04 279.33);
--muted: oklch(0.91 0.01 264.51);
--muted-foreground: oklch(0.55 0.03 279.08);
- --accent: oklch(0.55 0.25 297.02 / 60%);
- --accent-foreground: oklch(1.0 0 0);
+ --accent: oklch(0.5 0.18 297.02 / 60%);
+ --accent-foreground: oklch(1 0 0);
--destructive: oklch(0.55 0.22 19.81);
--border: oklch(0.81 0.02 271.2);
--input: oklch(0.86 0.01 268.48);
- --ring: oklch(0.55 0.25 297.02);
- --chart-1: oklch(0.55 0.25 297.02);
- --chart-2: oklch(0.55 0.25 297.02 / 60%);
+ --ring: oklch(0.5 0.18 297.02);
+ --chart-1: oklch(0.5 0.18 297.02);
+ --chart-2: oklch(0.5 0.18 297.02 / 60%);
--chart-3: oklch(0.63 0.18 140.44);
--chart-4: oklch(0.69 0.2 42.43);
--chart-5: oklch(0.71 0.1 33.1);
--sidebar: oklch(0.93 0.01 264.52);
--sidebar-foreground: oklch(0.44 0.04 279.33);
- --sidebar-primary: oklch(0.55 0.25 297.02);
- --sidebar-primary-foreground: oklch(1.0 0 0);
- --sidebar-accent: oklch(0.55 0.25 297.02 / 60%);
- --sidebar-accent-foreground: oklch(1.0 0 0);
+ --sidebar-primary: oklch(0.5 0.18 297.02);
+ --sidebar-primary-foreground: oklch(1 0 0);
+ --sidebar-accent: oklch(0.5 0.18 297.02 / 60%);
+ --sidebar-accent-foreground: oklch(1 0 0);
--sidebar-border: oklch(0.81 0.02 271.2);
- --sidebar-ring: oklch(0.55 0.25 297.02);
- --destructive-foreground: oklch(1.0 0 0);
+ --sidebar-ring: oklch(0.5 0.18 297.02);
+ --destructive-foreground: oklch(1 0 0);
--font-sans: Montserrat, sans-serif;
--font-serif: Georgia, serif;
--font-mono: Fira Code, monospace;
@@ -213,31 +213,31 @@
--card-foreground: oklch(0.88 0.04 272.28);
--popover: oklch(0.4 0.03 280.15);
--popover-foreground: oklch(0.88 0.04 272.28);
- --primary: oklch(0.79 0.12 304.77);
+ --primary: oklch(0.69 0.08 304.77);
--primary-foreground: oklch(0.24 0.03 283.91);
--secondary: oklch(0.48 0.03 278.64);
--secondary-foreground: oklch(0.88 0.04 272.28);
--muted: oklch(0.3 0.03 276.21);
--muted-foreground: oklch(0.75 0.04 273.93);
- --accent: oklch(0.79 0.12 304.77 / 60%);
+ --accent: oklch(0.69 0.08 304.77 / 60%);
--accent-foreground: oklch(0.24 0.03 283.91);
--destructive: oklch(0.76 0.13 2.76);
--border: oklch(0.32 0.03 281.98);
--input: oklch(0.32 0.03 281.98);
- --ring: oklch(0.79 0.12 304.77);
- --chart-1: oklch(0.79 0.12 304.77);
- --chart-2: oklch(0.79 0.12 304.77 / 60%);
+ --ring: oklch(0.69 0.08 304.77);
+ --chart-1: oklch(0.69 0.08 304.77);
+ --chart-2: oklch(0.69 0.08 304.77 / 60%);
--chart-3: oklch(0.86 0.11 142.72);
--chart-4: oklch(0.82 0.1 52.63);
--chart-5: oklch(0.92 0.02 30.49);
--sidebar: oklch(0.18 0.02 284.2);
--sidebar-foreground: oklch(0.88 0.04 272.28);
- --sidebar-primary: oklch(0.79 0.12 304.77);
+ --sidebar-primary: oklch(0.69 0.08 304.77);
--sidebar-primary-foreground: oklch(0.24 0.03 283.91);
- --sidebar-accent: oklch(0.79 0.12 304.77 / 60%);
+ --sidebar-accent: oklch(0.69 0.08 304.77 / 60%);
--sidebar-accent-foreground: oklch(0.24 0.03 283.91);
--sidebar-border: oklch(0.4 0.03 280.15);
- --sidebar-ring: oklch(0.79 0.12 304.77);
+ --sidebar-ring: oklch(0.69 0.08 304.77);
--destructive-foreground: oklch(0.24 0.03 283.91);
--radius: 0.35rem;
--font-sans: Montserrat, sans-serif;
diff --git a/apps/web/src/app/showcase/_components/ShowcaseItem.tsx b/apps/web/src/app/showcase/_components/ShowcaseItem.tsx
new file mode 100644
index 0000000..8068171
--- /dev/null
+++ b/apps/web/src/app/showcase/_components/ShowcaseItem.tsx
@@ -0,0 +1,90 @@
+"use client";
+
+import { motion } from "motion/react";
+import Image from "next/image";
+import Link from "next/link";
+
+export interface ShowcaseItemProps {
+ title: string;
+ description: string;
+ imageUrl: string;
+ liveUrl?: string;
+ sourceUrl?: string;
+ tags: string[];
+}
+
+export default function ShowcaseItem({
+ title,
+ description,
+ imageUrl,
+ liveUrl,
+ sourceUrl,
+ tags,
+}: ShowcaseItemProps) {
+ const itemVariants = {
+ hidden: { opacity: 0, y: 20 },
+ visible: {
+ opacity: 1,
+ y: 0,
+ transition: {
+ duration: 0.5,
+ ease: "easeOut",
+ },
+ },
+ };
+
+ return (
+
+
+
+
+
+ {title}
+
+
+ {description}
+
+
+ {tags.map((tag) => (
+
+ {tag}
+
+ ))}
+
+
+ {liveUrl && (
+
+ Live Demo
+
+ )}
+ {sourceUrl && (
+
+ Source Code
+
+ )}
+
+
+ );
+}
diff --git a/apps/web/src/app/showcase/page.tsx b/apps/web/src/app/showcase/page.tsx
new file mode 100644
index 0000000..d51c889
--- /dev/null
+++ b/apps/web/src/app/showcase/page.tsx
@@ -0,0 +1,90 @@
+"use client";
+
+import { motion } from "motion/react";
+import Navbar from "../(home)/_components/navbar";
+import ShowcaseItem from "./_components/ShowcaseItem";
+
+const showcaseProjects = [
+ {
+ title: "Project Alpha",
+ description: "A cool project built with Better-T-Stack.",
+ imageUrl: "https://via.placeholder.com/400x300?text=Project+Alpha",
+ liveUrl: "#",
+ sourceUrl: "#",
+ tags: ["Next.js", "tRPC", "Drizzle"],
+ },
+ {
+ title: "Beta App",
+ description: "Another awesome application powered by Better-T-Stack.",
+ imageUrl: "https://via.placeholder.com/400x300?text=Beta+App",
+ liveUrl: "#",
+ sourceUrl: "#",
+ tags: ["Hono", "React Native", "SQLite"],
+ },
+ {
+ title: "Gamma Platform",
+ description: "Showcasing the versatility of Better-T-Stack.",
+ imageUrl: "https://via.placeholder.com/400x300?text=Gamma+Platform",
+ liveUrl: "#",
+ tags: ["Convex", "TanStack Router"],
+ },
+];
+
+export default function ShowcasePage() {
+ const containerVariants = {
+ hidden: { opacity: 0 },
+ visible: {
+ opacity: 1,
+ transition: {
+ staggerChildren: 0.1,
+ delayChildren: 0.2,
+ },
+ },
+ };
+
+ const itemVariants = {
+ hidden: { opacity: 0, y: 20 },
+ visible: {
+ opacity: 1,
+ y: 0,
+ transition: {
+ duration: 0.5,
+ ease: "easeOut",
+ },
+ },
+ };
+
+ return (
+ <>
+
+
+
+
+
+
+ Showcase
+
+
+
+ Discover amazing projects built with Better-T-Stack.
+
+
+
+
+ {showcaseProjects.map((project) => (
+
+ ))}
+
+
+
+ >
+ );
+}
diff --git a/bun.lock b/bun.lock
index e2fbbc3..24ea604 100644
--- a/bun.lock
+++ b/bun.lock
@@ -14,7 +14,7 @@
},
"apps/cli": {
"name": "create-better-t-stack",
- "version": "2.11.0",
+ "version": "2.12.0",
"bin": {
"create-better-t-stack": "dist/index.js",
},
diff --git a/package.json b/package.json
index 76f5ee1..baa2db8 100644
--- a/package.json
+++ b/package.json
@@ -10,6 +10,7 @@
"build:web": "turbo run build --filter=web",
"build:cli": "turbo run build --filter=create-better-t-stack",
"check": "turbo check",
+ "format": "biome check --write .",
"publish-packages": "turbo run build --filter=create-better-t-stack && changeset publish",
"build:web:cloudflare": "bun install && bun run build:web",
"deploy:web": "bun run build:web:cloudflare && bunx wrangler pages deploy ./apps/web/out"