Julius Polar

My Tech Stack

Posted

This site is built with my preferred tech stack — picked for two things: speed, and how well it plays with coding agents.

Vite Ecosystem

Vite is the build tool underneath it all — it’s fast, requires almost no config, and works with everything.

Vitest for unit and component tests.

oxlint for linting and oxfmt for formatting — both use my own @julianelda/lexis package, and both are faster than ESLint and Prettier, which matters for a tighter agent feedback loop. I still keep ESLint around because oxlint doesn’t fully support it yet.

Tooling

Bun is the package manager and runtime. Claude Code runs on Bun, for what it’s worth.

Storybook for building and browsing components in isolation.

Lefthook for git hooks — no Node startup per commit like Husky, and hooks run in parallel instead of one after another.

nano-staged auto-lints and auto-formats staged files on pre-commit. Leaner than lint-staged.

{
  "**/*.{js,jsx,ts,tsx}": ["oxlint --fix", "oxfmt"],
  "**/*.{css,html,json,yaml,yml,md}": "oxfmt",
  "**/*.{svelte}": ["oxlint --fix", "oxfmt"]
}

commitlint enforces conventional commit messages.

Testing

Playwright for end-to-end tests. Playwright CLI also lets an agent open a browser and see the app directly.

@vitest/browser-playwright for running Vitest’s browser-mode tests through Playwright.

Styling

Tailwind CSS for utility-first styling — once you’re used to it, you can see a component’s styles without jumping through multiple CSS files, and the media query syntax is intuitive enough that you stop thinking about breakpoint variable names.

Agents

A couple of things for the agents.

AGENTS.md covers general code conventions — naming, TypeScript, Svelte, styling, testing.

CLAUDE.md covers general architecture — project shape, content, API structure. I prefer to ask the agent (I use Claude) to scan the repo and have it write the file.

Claude Code hooks in .claude/settings.json auto-lint and auto-format after every tool use, so the produced code always meets the repo’s lint and formatting standards. It’s also cheaper to run a script than to burn AI tokens getting an agent to match the style by hand.

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit|MultiEdit|Bash",
        "hooks": [
          {
            "type": "command",
            "command": "cd $(git rev-parse --show-toplevel) && ./node_modules/.bin/nano-staged --unstaged --quiet --bail"
          }
        ]
      }
    ],
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "cd $(git rev-parse --show-toplevel) && ./node_modules/.bin/nano-staged --unstaged --quiet --bail"
          }
        ]
      }
    ]
  }
}

On the horizon

Vite+ would fold oxfmt, oxlint, vite, vitest into a single library. Typescript 7.1 is expected to ship programmatic API for Svelte tooling that currently still need Typescript 6.