From 6f67a0dc1a96bf43eb86388b9acfe54c30d7ecc9 Mon Sep 17 00:00:00 2001 From: jasmine Date: Mon, 27 Oct 2025 20:02:55 +0800 Subject: [PATCH] Initial commit: minimal JavaScript template with Nix Features: - Nix + Flakes for reproducible environments - Bun (fast JavaScript runtime) - Vite (development server & build tool) - ESLint + Prettier (linting & formatting) - Devshell commands via just - Modular structure using flake-parts - Omnix template support for initialization --- .envrc | 1 + .gitignore | 9 +++++ .prettierignore | 6 +++ Justfile | 58 +++++++++++++++++++++++++++++ LICENSE | 21 +++++++++++ README.md | 51 ++++++++++++++++++++++++++ bun.lockb | Bin 0 -> 24546 bytes eslint.config.js | 13 +++++++ flake.lock | 77 +++++++++++++++++++++++++++++++++++++++ flake.nix | 18 +++++++++ index.html | 13 +++++++ nix/modules/devshell.nix | 43 ++++++++++++++++++++++ nix/modules/template.nix | 19 ++++++++++ package.json | 13 +++++++ src/main.js | 8 ++++ src/style.css | 35 ++++++++++++++++++ 16 files changed, 385 insertions(+) create mode 100644 .envrc create mode 100644 .gitignore create mode 100644 .prettierignore create mode 100644 Justfile create mode 100644 LICENSE create mode 100644 README.md create mode 100755 bun.lockb create mode 100644 eslint.config.js create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 index.html create mode 100644 nix/modules/devshell.nix create mode 100644 nix/modules/template.nix create mode 100644 package.json create mode 100644 src/main.js create mode 100644 src/style.css diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..3550a30 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..248e5ac --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +# Dependencies +node_modules/ + +# Build output +dist/ +build/ + +# Direnv +.direnv/ diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..a239a33 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,6 @@ +# Dependencies +node_modules + +# Build output +dist +build diff --git a/Justfile b/Justfile new file mode 100644 index 0000000..0ce057f --- /dev/null +++ b/Justfile @@ -0,0 +1,58 @@ +# List available commands +default: + @just --list + +# Start development server with hot reload +dev: + bun run dev + +# Add a package dependency +add package: + bun add {{package}} + +# Add a dev dependency +add-dev package: + bun add -d {{package}} + +# Remove a package dependency +remove package: + bun remove {{package}} + +# Build for production +build: + bun run build + +# Preview production build +preview: + bun run preview + +# Install dependencies +install: + bun install + +# Update flake inputs +update: + nix flake update + +# Clean build artifacts and dependencies +clean: + rm -rf dist node_modules bun.lockb + +# Format code with prettierd +format: + prettierd --write . + +# Check formatting without making changes +format-check: + prettierd --check . + +# Lint code with eslint +lint: + eslint . + +# Lint and auto-fix issues +lint-fix: + eslint --fix . + +# Check both formatting and linting +check: format-check lint diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..461f024 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 sajenim + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..24cd418 --- /dev/null +++ b/README.md @@ -0,0 +1,51 @@ +# JavaScript Template + +A minimal JavaScript development template using Nix. Key features: + +- Nix + Flakes for reproducible environments +- Bun (fast JavaScript runtime) +- Vite (development server & build tool) +- ESLint + Prettier (linting & formatting) +- Devshell commands via just + +## Prerequisites + +- [Nix](https://nixos.org/download.html) with flakes enabled +- [direnv](https://direnv.net/) (optional but recommended) + +## Getting Started + +Initialize a new project using [omnix](https://omnix.page): + +```sh +nix run nixpkgs#omnix -- \ + init github:sajenim/javascript-template -o ./my-project +``` + +Then enter the development environment: + +```sh +cd my-project +direnv allow # Or use: nix develop +just dev +``` + +**NixOS users:** If bun-installed binaries fail to find system libraries, enable FHS compatibility: + +```nix +# nix/modules/devshell.nix +fhs = true; +``` + +## Customization + +This template provides minimal, sensible defaults. Customize as needed: + +- Add dependencies: `just add ` +- Modify linting rules in `eslint.config.js` +- Add Prettier config via `.prettierrc` if needed +- Extend `Justfile` with project-specific commands + +## Acknowledgments + +- [srid's haskell-template](https://github.com/srid/haskell-template) diff --git a/bun.lockb b/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..56a97aab72706d69e004b0e466b97e5aea67c44e GIT binary patch literal 24546 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 aQEf=G6+B1@YQO4&CyYSNTF~tAV8j6DB5&pZ literal 0 HcmV?d00001 diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..78300bc --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,13 @@ +export default [ + { + ignores: ["dist", "build", "node_modules"], + }, + { + files: ["**/*.js"], + languageOptions: { + ecmaVersion: "latest", + sourceType: "module", + }, + rules: {}, + }, +]; diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..395470a --- /dev/null +++ b/flake.lock @@ -0,0 +1,77 @@ +{ + "nodes": { + "flake-parts": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1760948891, + "narHash": "sha256-TmWcdiUUaWk8J4lpjzu4gCGxWY6/Ok7mOK4fIFfBuU4=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "864599284fc7c0ba6357ed89ed5e2cd5040f0c04", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1751274312, + "narHash": "sha256-/bVBlRpECLVzjV19t5KMdMFWSwKLtb5RyXdjz3LJT+g=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "50ab793786d9de88ee30ec4e4c24fb4236fc2674", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-24.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "lastModified": 1754788789, + "narHash": "sha256-x2rJ+Ovzq0sCMpgfgGaaqgBSwY+LST+WbZ6TytnT9Rk=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "a73b9c743612e4244d865a2fdee11865283c04e6", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-parts": "flake-parts", + "nixpkgs": "nixpkgs", + "systems": "systems" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..2fa174a --- /dev/null +++ b/flake.nix @@ -0,0 +1,18 @@ +{ + description = "Nix template for JavaScript projects, powered by Bun"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11"; + systems.url = "github:nix-systems/default"; + flake-parts.url = "github:hercules-ci/flake-parts"; + }; + + outputs = inputs: + inputs.flake-parts.lib.mkFlake {inherit inputs;} { + systems = import inputs.systems; + imports = [ + ./nix/modules/devshell.nix + ./nix/modules/template.nix + ]; + }; +} diff --git a/index.html b/index.html new file mode 100644 index 0000000..111f7e3 --- /dev/null +++ b/index.html @@ -0,0 +1,13 @@ + + + + + + JavaScript App + + + +
+ + + diff --git a/nix/modules/devshell.nix b/nix/modules/devshell.nix new file mode 100644 index 0000000..70265b1 --- /dev/null +++ b/nix/modules/devshell.nix @@ -0,0 +1,43 @@ +{inputs, lib, ...}: let + # FHS compatibility for NixOS (steam-run wrapper) + # Enable if bun-installed binaries fail to find system libraries + fhs = false; +in { + perSystem = {system, ...}: let + pkgs = import inputs.nixpkgs { + inherit system; + config.allowUnfree = fhs; + }; + + fhsPackages = lib.optionals fhs [ + pkgs.steam-run + ]; + + fhsSetup = lib.optionalString fhs '' + alias bun="steam-run bun" + ''; + in { + devShells.default = pkgs.mkShell { + nativeBuildInputs = with pkgs; + [ + bun + eslint + just + prettierd + ] + ++ fhsPackages; + + shellHook = '' + ${fhsSetup} + + if [ -f package.json ]; then + echo "Installing dependencies..." + bun install + fi + + echo "" + echo "💡 Run 'just' to see available commands" + ''; + }; + }; +} diff --git a/nix/modules/template.nix b/nix/modules/template.nix new file mode 100644 index 0000000..c936a64 --- /dev/null +++ b/nix/modules/template.nix @@ -0,0 +1,19 @@ +{inputs, ...}: { + flake = rec { + templates.default = { + description = "A minimal JavaScript project template with Bun and Nix"; + path = inputs.self; + }; + + om.templates.javascript-template = { + template = templates.default; + params = [ + { + name = "package-name"; + description = "Name of the JavaScript package"; + placeholder = "javascript-template"; + } + ]; + }; + }; +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..9cf1dc5 --- /dev/null +++ b/package.json @@ -0,0 +1,13 @@ +{ + "name": "javascript-template", + "version": "1.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "devDependencies": { + "vite": "^6.0.0" + } +} diff --git a/src/main.js b/src/main.js new file mode 100644 index 0000000..9721113 --- /dev/null +++ b/src/main.js @@ -0,0 +1,8 @@ +const app = document.getElementById("app"); + +app.innerHTML = ` +

JavaScript Template

+

Edit src/main.js to get started.

+`; + +console.log("Development server running"); diff --git a/src/style.css b/src/style.css new file mode 100644 index 0000000..ca371ab --- /dev/null +++ b/src/style.css @@ -0,0 +1,35 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: system-ui, -apple-system, sans-serif; + line-height: 1.6; + padding: 2rem; + background: #f5f5f5; + color: #333; +} + +#app { + 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; +} + +code { + padding: 0.2em 0.4em; + background: #f0f0f0; + border-radius: 3px; + font-family: "Monaco", "Courier New", monospace; + font-size: 0.9em; +}