create-audora-next 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +54 -0
  3. package/index.ts +81 -0
  4. package/package.json +34 -0
  5. package/templates/base/README.md +152 -0
  6. package/templates/base/eslint.config.mjs +18 -0
  7. package/templates/base/lint-staged.config.mjs +17 -0
  8. package/templates/base/next.config.ts +38 -0
  9. package/templates/base/package.json +52 -0
  10. package/templates/base/postcss.config.mjs +7 -0
  11. package/templates/base/public/favicon/apple-touch-icon.png +0 -0
  12. package/templates/base/public/favicon/favicon-96x96.png +0 -0
  13. package/templates/base/public/favicon/favicon.ico +0 -0
  14. package/templates/base/public/favicon/favicon.svg +1 -0
  15. package/templates/base/public/favicon/site.webmanifest +21 -0
  16. package/templates/base/public/favicon/web-app-manifest-192x192.png +0 -0
  17. package/templates/base/public/favicon/web-app-manifest-512x512.png +0 -0
  18. package/templates/base/public/images/screenshot-desktop-dark.webp +0 -0
  19. package/templates/base/public/images/screenshot-desktop-light.webp +0 -0
  20. package/templates/base/public/images/screenshot-mobile-dark.webp +0 -0
  21. package/templates/base/public/images/screenshot-mobile-light.webp +0 -0
  22. package/templates/base/src/app/layout.tsx +52 -0
  23. package/templates/base/src/app/llms-full.txt/route.ts +97 -0
  24. package/templates/base/src/app/llms.txt/route.ts +40 -0
  25. package/templates/base/src/app/manifest.ts +61 -0
  26. package/templates/base/src/app/page.tsx +63 -0
  27. package/templates/base/src/app/robots.ts +16 -0
  28. package/templates/base/src/app/sitemap.ts +41 -0
  29. package/templates/base/src/components/copyable-code.tsx +41 -0
  30. package/templates/base/src/components/icons.tsx +84 -0
  31. package/templates/base/src/components/theme-provider.tsx +11 -0
  32. package/templates/base/src/components/theme-toggle.tsx +20 -0
  33. package/templates/base/src/config/site.ts +18 -0
  34. package/templates/base/src/data/llms.ts +112 -0
  35. package/templates/base/src/data/site.ts +30 -0
  36. package/templates/base/src/lib/seo.ts +190 -0
  37. package/templates/base/src/styles/globals.css +27 -0
  38. package/templates/base/src/utils/cn.ts +7 -0
  39. package/templates/base/tsconfig.json +34 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Audora Labs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,54 @@
1
+ # create-audora-next
2
+
3
+ Create a new Audora Next.js app with one command.
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ bunx create-audora-next my-app
9
+ ```
10
+
11
+ Then follow the prompts, or use:
12
+
13
+ ```bash
14
+ cd my-app
15
+ cp .env.example .env
16
+ bun dev
17
+ ```
18
+
19
+ Open [http://localhost:3000](http://localhost:3000) to see your app.
20
+
21
+ ## Available Templates
22
+
23
+ | Template | Status |
24
+ | -------- | ----------- |
25
+ | `base` | Available |
26
+ | `blog` | Coming Soon |
27
+
28
+ ## Base Template Features
29
+
30
+ - Next.js 16 with App Router & Turbopack
31
+ - React 19 with React Compiler
32
+ - TypeScript 5 (strict mode)
33
+ - Tailwind CSS 4
34
+ - Bun runtime
35
+ - Open Graph & Twitter Cards
36
+ - Structured Data (JSON-LD)
37
+ - Dynamic robots.txt & sitemap.xml
38
+ - llms.txt for AI assistants
39
+ - PWA Manifest
40
+ - Security headers
41
+ - Dark mode with next-themes
42
+ - Geist font
43
+ - ESLint 9 flat config
44
+ - Prettier with Tailwind plugin
45
+ - Husky & lint-staged
46
+ - Path alias (`@/*`)
47
+
48
+ ## Requirements
49
+
50
+ - [Bun](https://bun.sh) v1.0.0 or higher
51
+
52
+ ## License
53
+
54
+ [MIT](LICENSE)
package/index.ts ADDED
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import { mkdirSync, cpSync, existsSync } from "fs";
4
+ import { join } from "path";
5
+ import { execSync } from "child_process";
6
+ import pc from "picocolors";
7
+ import ora from "ora";
8
+
9
+ const projectName = process.argv[2];
10
+
11
+ // Validate project name
12
+ if (!projectName) {
13
+ console.error(`\n${pc.red("Error:")} Please provide a project name.`);
14
+ console.log(
15
+ `\nUsage: ${pc.cyan("bunx create-audora-next")} ${pc.green(
16
+ "<project-name>"
17
+ )}\n`
18
+ );
19
+ process.exit(1);
20
+ }
21
+
22
+ if (!/^[a-zA-Z0-9_-]+$/.test(projectName)) {
23
+ console.error(
24
+ `\n${pc.red(
25
+ "Error:"
26
+ )} Project name can only contain letters, numbers, hyphens, and underscores.`
27
+ );
28
+ process.exit(1);
29
+ }
30
+
31
+ const targetDir = join(process.cwd(), projectName);
32
+
33
+ if (existsSync(targetDir)) {
34
+ console.error(
35
+ `\n${pc.red("Error:")} Directory ${pc.cyan(projectName)} already exists.`
36
+ );
37
+ process.exit(1);
38
+ }
39
+
40
+ console.log(
41
+ `\nCreating a new ${pc.bold("Audora Next")} app in ${pc.cyan(targetDir)}...\n`
42
+ );
43
+
44
+ // Copy template
45
+ mkdirSync(targetDir);
46
+ cpSync(new URL("./templates/base", import.meta.url), targetDir, {
47
+ recursive: true,
48
+ });
49
+
50
+ process.chdir(targetDir);
51
+
52
+ // Init git (optional - warn if git not available)
53
+ const gitSpinner = ora("Initializing git repository...").start();
54
+ try {
55
+ execSync("git init", { stdio: "pipe" });
56
+ gitSpinner.succeed("Initialized git repository");
57
+ } catch {
58
+ gitSpinner.warn("Could not initialize git repository. Is git installed?");
59
+ }
60
+
61
+ // Install deps
62
+ const installSpinner = ora("Installing dependencies...").start();
63
+ try {
64
+ execSync("bun install", { stdio: "pipe" });
65
+ installSpinner.succeed("Installed dependencies");
66
+ } catch {
67
+ installSpinner.fail("Failed to install dependencies");
68
+ console.error(
69
+ `\n${pc.red("Error:")} Please run ${pc.cyan("bun install")} manually.\n`
70
+ );
71
+ process.exit(1);
72
+ }
73
+
74
+ console.log(`
75
+ ${pc.green("Success!")} Created ${pc.bold(projectName)} at ${pc.cyan(targetDir)}
76
+
77
+ ${pc.bold("Next steps:")}
78
+ ${pc.cyan("cd")} ${projectName}
79
+ ${pc.cyan("cp .env.example .env")}
80
+ ${pc.cyan("bun dev")}
81
+ `);
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "create-audora-next",
3
+ "version": "0.1.1",
4
+ "description": "Create a new Audora Next.js app with one command",
5
+ "keywords": [
6
+ "create",
7
+ "next",
8
+ "nextjs",
9
+ "bun",
10
+ "starter",
11
+ "template",
12
+ "audora"
13
+ ],
14
+ "type": "module",
15
+ "license": "MIT",
16
+ "private": false,
17
+ "bin": {
18
+ "create-audora-next": "./index.ts"
19
+ },
20
+ "files": [
21
+ "index.ts",
22
+ "templates"
23
+ ],
24
+ "devDependencies": {
25
+ "@types/bun": "latest"
26
+ },
27
+ "engines": {
28
+ "bun": ">=1.0.0"
29
+ },
30
+ "dependencies": {
31
+ "ora": "^9.0.0",
32
+ "picocolors": "^1.1.1"
33
+ }
34
+ }
@@ -0,0 +1,152 @@
1
+ # next-starter
2
+
3
+ A production-ready Next.js starter with enterprise-level SEO, security headers, and modern tooling. Clone, customize, and ship.
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ bunx degit audoralabs/next-starter my-app
9
+ cd my-app
10
+ git init
11
+ bun install
12
+ bun dev
13
+ ```
14
+
15
+ Open [http://localhost:3000](http://localhost:3000) to see your app.
16
+
17
+ ## What's Included
18
+
19
+ ### Core Stack
20
+
21
+ | Technology | Version | Notes |
22
+ | ------------ | ------- | ------------------------------ |
23
+ | Next.js | 16.1.1 | App Router, Turbopack enabled |
24
+ | React | 19.2.3 | React Compiler enabled |
25
+ | TypeScript | 5 | Strict mode |
26
+ | Tailwind CSS | 4 | PostCSS, no config file needed |
27
+ | Bun | Latest | Package manager and runtime |
28
+
29
+ ### SEO
30
+
31
+ This starter ships with everything you need for search engine optimization:
32
+
33
+ - **Open Graph & Twitter Cards** - Complete social sharing metadata
34
+ - **Structured Data (JSON-LD)** - WebSite, Organization, and Breadcrumb schemas
35
+ - **Dynamic robots.txt** - Generated from `robots.ts`
36
+ - **Dynamic sitemap.xml** - Generated from `sitemap.ts`
37
+ - **llms.txt** - AI-friendly documentation for LLM assistants
38
+ - **Title Templates** - Consistent page titles with `%s - Site Name` pattern
39
+ - **Canonical URLs** - Prevent duplicate content issues
40
+ - **PWA Manifest** - Web app manifest with icons and screenshots
41
+
42
+ ### Security
43
+
44
+ Pre-configured security headers in `next.config.ts`:
45
+
46
+ - `X-Content-Type-Options: nosniff`
47
+ - `X-Frame-Options: DENY`
48
+ - `X-XSS-Protection: 1; mode=block`
49
+ - `Referrer-Policy: strict-origin-when-cross-origin`
50
+ - `Permissions-Policy` - Camera, microphone, geolocation disabled
51
+
52
+ ### Developer Experience
53
+
54
+ - **ESLint 9** - Flat config with Next.js rules
55
+ - **Prettier** - With Tailwind CSS plugin for class sorting
56
+ - **Husky** - Git hooks for pre-commit linting
57
+ - **lint-staged** - Run linters on staged files only
58
+ - **Path Alias** - `@/*` mapped to `./src/*`
59
+
60
+ > **Note:** Git hooks (Husky) are installed automatically when a Git repository is present.
61
+ > If you initialize Git after installing dependencies, re-run `bun install` to enable hooks.
62
+
63
+ - **Type Checking** - Dedicated `check-types` script
64
+
65
+ ### UI
66
+
67
+ - **Dark Mode** - System preference detection with next-themes
68
+ - **Geist Font** - Pre-configured sans and mono variants
69
+ - **cn() Utility** - Combines clsx and tailwind-merge
70
+
71
+ ## Project Structure
72
+
73
+ ```
74
+ src/
75
+ ├── app/
76
+ │ ├── layout.tsx # Root layout with metadata and JSON-LD
77
+ │ ├── page.tsx # Home page
78
+ │ ├── manifest.ts # PWA web app manifest
79
+ │ ├── robots.ts # robots.txt generation
80
+ │ ├── sitemap.ts # sitemap.xml generation
81
+ │ ├── llms.txt/ # AI-friendly summary
82
+ │ └── llms-full.txt/ # AI-friendly full documentation
83
+ ├── components/
84
+ │ ├── icons.tsx # Icon components
85
+ │ ├── theme-provider.tsx # Theme context provider
86
+ │ └── theme-toggle.tsx # Dark/light mode toggle
87
+ ├── config/
88
+ │ └── site.ts # Site configuration exports
89
+ ├── data/
90
+ │ ├── site.ts # Site metadata (name, URL, description)
91
+ │ └── llms.ts # llms.txt content configuration
92
+ ├── lib/
93
+ │ └── seo.ts # SEO utilities and JSON-LD generators
94
+ ├── styles/
95
+ │ └── globals.css # Global styles and Tailwind imports
96
+ └── utils/
97
+ └── cn.ts # Class name merge utility
98
+ ```
99
+
100
+ ## Configuration
101
+
102
+ ### Site Metadata
103
+
104
+ Edit `src/data/site.ts` to customize your site:
105
+
106
+ ```typescript
107
+ const SITE_DATA = {
108
+ name: "my-app",
109
+ url: "https://my-app.com",
110
+ ogImage: "https://my-app.com/og.png",
111
+ tagline: "Your tagline here",
112
+ description: "Your full description",
113
+ twitterHandle: "@myapp",
114
+ keywords: ["keyword1", "keyword2"],
115
+ };
116
+ ```
117
+
118
+ ### LLMs.txt Content
119
+
120
+ Edit `src/data/llms.ts` to customize AI-friendly documentation.
121
+
122
+ ## Scripts
123
+
124
+ | Command | Description |
125
+ | ---------------------- | -------------------------------- |
126
+ | `bun dev` | Start dev server with Turbopack |
127
+ | `bun run build` | Build for production |
128
+ | `bun start` | Start production server |
129
+ | `bun lint` | Run ESLint |
130
+ | `bun lint:fix` | Run ESLint with auto-fix |
131
+ | `bun check-types` | Run TypeScript type checking |
132
+ | `bun format` | Format all files with Prettier |
133
+ | `bun format:check` | Check formatting without writing |
134
+ | `bun clean` | Remove .next and node_modules |
135
+ | `bun upgrade:next` | Upgrade Next.js to latest |
136
+ | `bun upgrade:tailwind` | Upgrade Tailwind CSS |
137
+
138
+ ## Why These Choices
139
+
140
+ **Bun** - Faster installs, native TypeScript, smaller lockfile.
141
+
142
+ **App Router** - Server components, streaming, better layouts. Pages Router is legacy.
143
+
144
+ **React Compiler** - Automatic memoization without manual `useMemo`/`useCallback`.
145
+
146
+ **Tailwind CSS 4** - Native CSS layers, `@theme` directive, no config file for basics.
147
+
148
+ **ESLint Flat Config** - Cleaner, more composable than `.eslintrc` files.
149
+
150
+ **No Component Library** - Start clean, add shadcn/ui or Radix when needed.
151
+
152
+ **Turbopack** - Faster dev server and builds.
@@ -0,0 +1,18 @@
1
+ import { defineConfig, globalIgnores } from "eslint/config";
2
+ import nextVitals from "eslint-config-next/core-web-vitals";
3
+ import nextTs from "eslint-config-next/typescript";
4
+
5
+ const eslintConfig = defineConfig([
6
+ ...nextVitals,
7
+ ...nextTs,
8
+ // Override default ignores of eslint-config-next.
9
+ globalIgnores([
10
+ // Default ignores of eslint-config-next:
11
+ ".next/**",
12
+ "out/**",
13
+ "build/**",
14
+ "next-env.d.ts",
15
+ ]),
16
+ ]);
17
+
18
+ export default eslintConfig;
@@ -0,0 +1,17 @@
1
+ import path from "path";
2
+
3
+ // See https://nextjs.org/docs/app/api-reference/config/eslint#running-lint-on-staged-files for details
4
+ const buildEslintCommand = (filenames) =>
5
+ `eslint --fix ${filenames
6
+ .map((f) => `"${path.relative(process.cwd(), f)}"`)
7
+ .join(" ")}`;
8
+
9
+ /**
10
+ * @type {import('lint-staged').Configuration}
11
+ */
12
+ const lintStagedConfig = {
13
+ "*.{js,jsx,ts,tsx}": [buildEslintCommand, "prettier --write"],
14
+ "*.mdx": "prettier --write",
15
+ };
16
+
17
+ export default lintStagedConfig;
@@ -0,0 +1,38 @@
1
+ import type { NextConfig } from "next";
2
+
3
+ const nextConfig: NextConfig = {
4
+ reactCompiler: true,
5
+
6
+ async headers() {
7
+ return [
8
+ {
9
+ source: "/(.*)",
10
+ headers: [
11
+ {
12
+ key: "X-Content-Type-Options",
13
+ value: "nosniff",
14
+ },
15
+ {
16
+ key: "X-Frame-Options",
17
+ value: "DENY",
18
+ },
19
+ {
20
+ key: "X-XSS-Protection",
21
+ value: "1; mode=block",
22
+ },
23
+ {
24
+ key: "Referrer-Policy",
25
+ value: "strict-origin-when-cross-origin",
26
+ },
27
+ {
28
+ key: "Permissions-Policy",
29
+ value:
30
+ "camera=(), microphone=(), geolocation=(), browsing-topics=()",
31
+ },
32
+ ],
33
+ },
34
+ ];
35
+ },
36
+ };
37
+
38
+ export default nextConfig;
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "next-starter",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "dev": "next dev --turbopack",
7
+ "build": "next build --turbopack",
8
+ "start": "next start",
9
+ "lint": "eslint",
10
+ "lint:fix": "eslint --fix .",
11
+ "check-types": "tsc --noEmit --pretty",
12
+ "format:check": "prettier --check \"**/*.{ts,tsx,mdx}\" --cache",
13
+ "format:write": "prettier --write \"**/*.{ts,tsx,mdx}\" --cache",
14
+ "format": "prettier --write .",
15
+ "clean": "rm -rf .next node_modules",
16
+ "upgrade:next": "bunx @next/codemod@latest upgrade latest",
17
+ "upgrade:tailwind": "bunx @tailwindcss/upgrade@latest",
18
+ "prepare": "git rev-parse --is-inside-work-tree > /dev/null 2>&1 && husky || true"
19
+ },
20
+ "dependencies": {
21
+ "clsx": "^2.1.1",
22
+ "next": "16.1.1",
23
+ "next-themes": "^0.4.6",
24
+ "react": "19.2.3",
25
+ "react-dom": "19.2.3",
26
+ "tailwind-merge": "^3.4.0"
27
+ },
28
+ "devDependencies": {
29
+ "@tailwindcss/postcss": "^4.1.18",
30
+ "@types/node": "^20.19.28",
31
+ "@types/react": "^19.2.8",
32
+ "@types/react-dom": "^19.2.3",
33
+ "babel-plugin-react-compiler": "1.0.0",
34
+ "eslint": "^9.39.2",
35
+ "eslint-config-next": "16.1.1",
36
+ "husky": "^9.1.7",
37
+ "lint-staged": "^16.2.7",
38
+ "prettier": "^3.7.4",
39
+ "prettier-plugin-tailwindcss": "^0.7.2",
40
+ "schema-dts": "^1.1.5",
41
+ "tailwindcss": "^4.1.18",
42
+ "typescript": "^5.9.3"
43
+ },
44
+ "ignoreScripts": [
45
+ "sharp",
46
+ "unrs-resolver"
47
+ ],
48
+ "trustedDependencies": [
49
+ "sharp",
50
+ "unrs-resolver"
51
+ ]
52
+ }
@@ -0,0 +1,7 @@
1
+ const config = {
2
+ plugins: {
3
+ "@tailwindcss/postcss": {},
4
+ },
5
+ };
6
+
7
+ export default config;
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="1000" height="1000"><g clip-path="url(#SvgjsClipPath1017)"><rect width="1000" height="1000" fill="#ffffff"></rect><g transform="matrix(2.5,0,0,2.5,0,0)"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="400" viewBox="0 0 400 400"><image width="400" height="400" xlink:href="data:image/jpeg;base64,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"></image></svg></g></g><defs><clipPath id="SvgjsClipPath1017"><rect width="1000" height="1000" x="0" y="0" rx="350" ry="350"></rect></clipPath></defs></svg>
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "Audora",
3
+ "short_name": "Audora",
4
+ "icons": [
5
+ {
6
+ "src": "/favicons/web-app-manifest-192x192.png",
7
+ "sizes": "192x192",
8
+ "type": "image/png",
9
+ "purpose": "maskable"
10
+ },
11
+ {
12
+ "src": "/favicons/web-app-manifest-512x512.png",
13
+ "sizes": "512x512",
14
+ "type": "image/png",
15
+ "purpose": "maskable"
16
+ }
17
+ ],
18
+ "theme_color": "#000000",
19
+ "background_color": "#000000",
20
+ "display": "standalone"
21
+ }
@@ -0,0 +1,52 @@
1
+ import type { Metadata, Viewport } from "next";
2
+ import { Geist, Geist_Mono } from "next/font/google";
3
+ import { ThemeProvider } from "@/components/theme-provider";
4
+ import {
5
+ getMetadata,
6
+ getViewport,
7
+ getWebSiteJsonLd,
8
+ getOrganizationJsonLd,
9
+ } from "@/lib/seo";
10
+ import "@/styles/globals.css";
11
+
12
+ const geistSans = Geist({
13
+ variable: "--font-geist-sans",
14
+ subsets: ["latin"],
15
+ });
16
+
17
+ const geistMono = Geist_Mono({
18
+ variable: "--font-geist-mono",
19
+ subsets: ["latin"],
20
+ });
21
+
22
+ export const metadata: Metadata = getMetadata();
23
+ export const viewport: Viewport = getViewport();
24
+
25
+ export default function RootLayout({
26
+ children,
27
+ }: Readonly<{
28
+ children: React.ReactNode;
29
+ }>) {
30
+ const jsonLd = [getWebSiteJsonLd(), getOrganizationJsonLd()];
31
+
32
+ return (
33
+ <html lang="en" suppressHydrationWarning>
34
+ <head>
35
+ <script
36
+ id="schema-ld"
37
+ type="application/ld+json"
38
+ dangerouslySetInnerHTML={{
39
+ __html: JSON.stringify(jsonLd).replace(/</g, "\\u003c"),
40
+ }}
41
+ />
42
+ </head>
43
+ <body
44
+ className={`${geistSans.variable} ${geistMono.variable} antialiased`}
45
+ >
46
+ <ThemeProvider attribute="class" defaultTheme="system" enableSystem>
47
+ {children}
48
+ </ThemeProvider>
49
+ </body>
50
+ </html>
51
+ );
52
+ }