diff --git a/.gitignore b/.gitignore index a5f9f41..3edc1cf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,16 +1,3 @@ -# Dependencies -node_modules/ -bun.lockb - -# Build output -dist/ -build/ -.next/ -out/ - -# TypeScript -*.tsbuildinfo -next-env.d.ts - -# Direnv +# Nix .direnv/ +result diff --git a/README.md b/README.md index f7d138e..9b86fb1 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,7 @@ TypeScript template with App Router for modern web applications. - Next.js 15 with App Router - React 19 - TypeScript +- Tailwind CSS (utility-first styling) - Optimized for Vercel deployment ## Shared Foundation @@ -153,9 +154,8 @@ All templates provide minimal, sensible defaults. Customize as needed: **Next.js:** - Configure Next.js in `next.config.js` -- Customize ESLint rules in `.eslintrc.json` +- Customize ESLint rules in `eslint.config.mjs` - Adjust TypeScript settings in `tsconfig.json` -- Extend ESLint config for stricter rules **Both templates:** @@ -165,17 +165,18 @@ All templates provide minimal, sensible defaults. Customize as needed: ## Template Comparison -| Feature | Vanilla | Next.js | -| ------------------ | ------- | ------- | -| Framework | None | Next.js | -| Language | JS | TS | -| Bundler | Vite | Next.js | -| Client-side only | ✓ | ✗ | -| Server-side API | ✗ | ✓ | -| Static generation | ✓ | ✓ | -| Type checking | ✗ | ✓ | -| React components | ✗ | ✓ | -| File-based routing | ✗ | ✓ | +| Feature | Vanilla | Next.js | +| ------------------ | ----------- | ----------- | +| Framework | None | Next.js | +| Language | JS | TS | +| Bundler | Vite | Next.js | +| Styling | Vanilla CSS | Tailwind v4 | +| Client-side only | ✓ | ✗ | +| Server-side API | ✗ | ✓ | +| Static generation | ✓ | ✓ | +| Type checking | ✗ | ✓ | +| React components | ✗ | ✓ | +| File-based routing | ✗ | ✓ | ## Acknowledgments diff --git a/nix/modules/template.nix b/nix/modules/template.nix index c7373dd..9e91bf4 100644 --- a/nix/modules/template.nix +++ b/nix/modules/template.nix @@ -15,7 +15,7 @@ in { }; om.templates = { - default = { + vanilla = { template = templates.default; params = [ { diff --git a/templates/nextjs/.eslintrc.json b/templates/nextjs/.eslintrc.json deleted file mode 100644 index 3722418..0000000 --- a/templates/nextjs/.eslintrc.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": ["next/core-web-vitals", "next/typescript"] -} diff --git a/templates/nextjs/.gitignore b/templates/nextjs/.gitignore new file mode 100644 index 0000000..cc18890 --- /dev/null +++ b/templates/nextjs/.gitignore @@ -0,0 +1,38 @@ +# Dependencies +node_modules + +# Next.js build output +.next +out + +# Production +build +dist + +# Nix +.direnv +result + +# Misc +.DS_Store +*.pem +*.log + +# Debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Bun +bun.lockb + +# Environment +.env +.env*.local + +# Vercel +.vercel + +# TypeScript +*.tsbuildinfo +next-env.d.ts diff --git a/templates/nextjs/app/globals.css b/templates/nextjs/app/globals.css index 362edd5..70731a5 100644 --- a/templates/nextjs/app/globals.css +++ b/templates/nextjs/app/globals.css @@ -1,3 +1,5 @@ +@import "tailwindcss"; + * { margin: 0; padding: 0; @@ -7,58 +9,6 @@ body { font-family: system-ui, -apple-system, sans-serif; line-height: 1.6; - padding: 2rem; background: #f5f5f5; color: #333; } - -main { - max-width: 800px; - margin: 0 auto; - padding: 2rem; - background: white; - border-radius: 8px; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); -} - -h1 { - margin-bottom: 1rem; - color: #2c3e50; -} - -p { - margin-bottom: 1.5rem; -} - -code { - padding: 0.2em 0.4em; - background: #f0f0f0; - border-radius: 3px; - font-family: 'Monaco', 'Courier New', monospace; - font-size: 0.9em; -} - -.container { - display: flex; - flex-direction: column; - gap: 1.5rem; -} - -.links { - display: flex; - gap: 1rem; - flex-wrap: wrap; -} - -.links a { - padding: 0.5rem 1rem; - background: #2c3e50; - color: white; - text-decoration: none; - border-radius: 4px; - transition: background 0.2s; -} - -.links a:hover { - background: #34495e; -} diff --git a/templates/nextjs/app/page.tsx b/templates/nextjs/app/page.tsx index 77db059..4c7a91a 100644 --- a/templates/nextjs/app/page.tsx +++ b/templates/nextjs/app/page.tsx @@ -1,18 +1,21 @@ export default function Home() { return ( -
-
-

Welcome to {{package-name}}

-

- A minimal Next.js TypeScript template with App Router, powered by - Bun and Nix. +

+
+

Welcome to {{package-name}}

+

+ A minimal Next.js TypeScript template with App Router, powered by Bun + and Nix.

- -
+

+ Edit app/page.tsx to get started. +

+
-
-
+ + + ); } diff --git a/templates/nextjs/eslint.config.mjs b/templates/nextjs/eslint.config.mjs new file mode 100644 index 0000000..bb4e553 --- /dev/null +++ b/templates/nextjs/eslint.config.mjs @@ -0,0 +1,16 @@ +import { defineConfig, globalIgnores } from 'eslint/config'; +import nextVitals from 'eslint-config-next/core-web-vitals'; + +const eslintConfig = defineConfig([ + ...nextVitals, + globalIgnores([ + '.next/**', + 'out/**', + 'build/**', + 'dist/**', + 'node_modules/**', + 'next-env.d.ts', + ]), +]); + +export default eslintConfig; diff --git a/templates/nextjs/flake.nix b/templates/nextjs/flake.nix index 3dde900..a307145 100644 --- a/templates/nextjs/flake.nix +++ b/templates/nextjs/flake.nix @@ -1,5 +1,5 @@ { - description = "Nix templates for JavaScript projects, powered by Bun"; + description = "Next.js TypeScript project with App Router, Bun, and Nix"; inputs = { nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11"; @@ -12,7 +12,6 @@ systems = import inputs.systems; imports = [ ./nix/modules/devshell.nix - ./nix/modules/template.nix ]; }; } diff --git a/templates/nextjs/nix/modules/template.nix b/templates/nextjs/nix/modules/template.nix deleted file mode 100644 index a167e16..0000000 --- a/templates/nextjs/nix/modules/template.nix +++ /dev/null @@ -1,41 +0,0 @@ -{inputs, ...}: let - root = inputs.self; -in { - flake = rec { - templates = { - default = { - description = "Minimal JavaScript template with Vite and Bun"; - path = "${root}/vanilla"; - }; - - nextjs = { - description = "Next.js TypeScript template with App Router"; - path = "${root}/nextjs"; - }; - }; - - om.templates = { - default = { - template = templates.default; - params = [ - { - name = "package-name"; - description = "Name of the JavaScript package"; - placeholder = "my-project"; - } - ]; - }; - - nextjs = { - template = templates.nextjs; - params = [ - { - name = "package-name"; - description = "Name of the Next.js project"; - placeholder = "my-nextjs-app"; - } - ]; - }; - }; - }; -} diff --git a/templates/nextjs/package.json b/templates/nextjs/package.json index 45be068..0484843 100644 --- a/templates/nextjs/package.json +++ b/templates/nextjs/package.json @@ -15,11 +15,14 @@ "react-dom": "^19.0.0" }, "devDependencies": { + "@tailwindcss/postcss": "^4.0.0", "@types/node": "^22.0.0", "@types/react": "^19.0.0", "@types/react-dom": "^19.0.0", "eslint": "^9.0.0", "eslint-config-next": "^15.0.0", + "postcss": "^8.4.0", + "tailwindcss": "^4.0.0", "typescript": "^5.6.0" } } diff --git a/templates/nextjs/postcss.config.mjs b/templates/nextjs/postcss.config.mjs new file mode 100644 index 0000000..a34a3d5 --- /dev/null +++ b/templates/nextjs/postcss.config.mjs @@ -0,0 +1,5 @@ +export default { + plugins: { + '@tailwindcss/postcss': {}, + }, +}; diff --git a/templates/vanilla/.gitignore b/templates/vanilla/.gitignore new file mode 100644 index 0000000..8c559ba --- /dev/null +++ b/templates/vanilla/.gitignore @@ -0,0 +1,23 @@ +# Dependencies +node_modules + +# Build output +dist +build + +# Nix +.direnv +result + +# Misc +.DS_Store +*.log +*.pem + +# Bun +bun.lockb + +# Environment +.env +.env.local +.env*.local diff --git a/templates/vanilla/eslint.config.js b/templates/vanilla/eslint.config.js index 78300bc..90ba601 100644 --- a/templates/vanilla/eslint.config.js +++ b/templates/vanilla/eslint.config.js @@ -1,13 +1,15 @@ -export default [ +import { defineConfig, globalIgnores } from 'eslint/config'; + +const eslintConfig = defineConfig([ + globalIgnores(['dist/**', 'build/**', 'node_modules/**']), { - ignores: ["dist", "build", "node_modules"], - }, - { - files: ["**/*.js"], + files: ['**/*.js'], languageOptions: { - ecmaVersion: "latest", - sourceType: "module", + ecmaVersion: 'latest', + sourceType: 'module', }, rules: {}, }, -]; +]); + +export default eslintConfig; diff --git a/templates/vanilla/flake.nix b/templates/vanilla/flake.nix index 3dde900..9b9385e 100644 --- a/templates/vanilla/flake.nix +++ b/templates/vanilla/flake.nix @@ -1,5 +1,5 @@ { - description = "Nix templates for JavaScript projects, powered by Bun"; + description = "Vanilla JavaScript project with Vite, Bun, and Nix"; inputs = { nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11"; @@ -12,7 +12,6 @@ systems = import inputs.systems; imports = [ ./nix/modules/devshell.nix - ./nix/modules/template.nix ]; }; } diff --git a/templates/vanilla/index.html b/templates/vanilla/index.html index 111f7e3..bcf8268 100644 --- a/templates/vanilla/index.html +++ b/templates/vanilla/index.html @@ -3,7 +3,7 @@ - JavaScript App + {{package-name}} diff --git a/templates/vanilla/nix/modules/devshell.nix b/templates/vanilla/nix/modules/devshell.nix index ca858e0..6b88beb 100644 --- a/templates/vanilla/nix/modules/devshell.nix +++ b/templates/vanilla/nix/modules/devshell.nix @@ -22,7 +22,6 @@ in { [ bun nodejs - typescript eslint just prettierd diff --git a/templates/vanilla/nix/modules/template.nix b/templates/vanilla/nix/modules/template.nix deleted file mode 100644 index a167e16..0000000 --- a/templates/vanilla/nix/modules/template.nix +++ /dev/null @@ -1,41 +0,0 @@ -{inputs, ...}: let - root = inputs.self; -in { - flake = rec { - templates = { - default = { - description = "Minimal JavaScript template with Vite and Bun"; - path = "${root}/vanilla"; - }; - - nextjs = { - description = "Next.js TypeScript template with App Router"; - path = "${root}/nextjs"; - }; - }; - - om.templates = { - default = { - template = templates.default; - params = [ - { - name = "package-name"; - description = "Name of the JavaScript package"; - placeholder = "my-project"; - } - ]; - }; - - nextjs = { - template = templates.nextjs; - params = [ - { - name = "package-name"; - description = "Name of the Next.js project"; - placeholder = "my-nextjs-app"; - } - ]; - }; - }; - }; -} diff --git a/templates/vanilla/package.json b/templates/vanilla/package.json index 9cf1dc5..50f912c 100644 --- a/templates/vanilla/package.json +++ b/templates/vanilla/package.json @@ -1,5 +1,5 @@ { - "name": "javascript-template", + "name": "{{package-name}}", "version": "1.0.0", "type": "module", "scripts": { diff --git a/templates/vanilla/src/main.js b/templates/vanilla/src/main.js index 9721113..a4b9415 100644 --- a/templates/vanilla/src/main.js +++ b/templates/vanilla/src/main.js @@ -1,7 +1,8 @@ const app = document.getElementById("app"); app.innerHTML = ` -

JavaScript Template

+

Welcome to {{package-name}}

+

A minimal JavaScript template with Vite, powered by Bun and Nix.

Edit src/main.js to get started.

`; diff --git a/templates/vanilla/src/style.css b/templates/vanilla/src/style.css index ca371ab..4ab5a49 100644 --- a/templates/vanilla/src/style.css +++ b/templates/vanilla/src/style.css @@ -26,6 +26,10 @@ h1 { color: #2c3e50; } +p { + margin-bottom: 1.5rem; +} + code { padding: 0.2em 0.4em; background: #f0f0f0;