A modern multi-tool web application — a Swiss Army knife in the browser. Each tool is a self-contained mini-app sharing a common shell, design system, and monorepo infrastructure.
- TypeScript 97.7%
- CSS 2.1%
- HTML 0.2%
| .agents/skills | ||
| .forgejo/workflows | ||
| .vscode | ||
| apps/web | ||
| packages | ||
| .gitignore | ||
| .oxfmtrc.json | ||
| .oxlintrc.json | ||
| AGENTS.md | ||
| bts.jsonc | ||
| LICENSE | ||
| package.json | ||
| pnpm-lock.yaml | ||
| pnpm-workspace.yaml | ||
| README.md | ||
| skills-lock.json | ||
| tsconfig.json | ||
| turbo.json | ||
Swiss Web
🧪 This project was built with AI assistance as a learning exercise.
A modern multi-tool web application — a Swiss Army knife in the browser. Each tool is a self-contained mini-app sharing a common shell, design system, and monorepo infrastructure.
Tech Stack
| Layer | Choice |
|---|---|
| Framework | Vite + React 19 |
| Router | TanStack Router (file-based, type-safe) |
| Styling | TailwindCSS 4 + tw-animate-css |
| Components | shadcn/ui (Base UI primitives) + lucide icons |
| Font | Rubik (Google Fonts) |
| Monorepo | Turborepo + pnpm workspaces |
| Language | TypeScript (strict) |
| Validation | Zod |
| Package manager | pnpm 11 |
Tools
| Tool | Description | Routes |
|---|---|---|
| Base64 | Encode/decode text ↔ Base64 strings | /tools/base64 |
| URL | Percent-encode/decode for safe URL transport | /tools/url |
| Date & Time | Four utilities for working with dates and times | /tools/date |
| ┣ Timestamp | Unix timestamp ↔ human-readable date converter | /tools/date/timestamp |
| ┣ Formatter | Parse any date string → 8 output formats | /tools/date/format |
| ┣ Timezone | Convert between timezones with full IANA TZ search | /tools/date/timezone |
| ┗ Diff | Calculate elapsed time between two dates | /tools/date/diff |
Every tool page includes a copy-to-clipboard button and structured table output.
Getting Started
pnpm install
pnpm run dev
Open http://localhost:5173 in your browser.
Project Structure
swiss-web/
├── apps/
│ └── web/ # Frontend SPA
│ └── src/
│ ├── routes/ # File-based TanStack routes
│ │ ├── __root.tsx # Shell: sidebar + header + outlet
│ │ ├── index.tsx # Home — tool dashboard
│ │ ├── tools.base64.tsx
│ │ ├── tools.base64.encode.tsx
│ │ ├── tools.base64.decode.tsx
│ │ ├── tools.url.tsx
│ │ ├── tools.url.encode.tsx
│ │ ├── tools.url.decode.tsx
│ │ ├── tools.date.tsx
│ │ ├── tools.date.timestamp.tsx
│ │ ├── tools.date.format.tsx
│ │ ├── tools.date.timezone.tsx
│ │ └── tools.date.diff.tsx
│ └── components/ # App shell (sidebar, header, theme)
├── packages/
│ ├── ui/ # shadcn/ui components + global CSS
│ │ ├── src/components/ # 16+ shared primitives
│ │ ├── src/hooks/ # use-mobile, etc.
│ │ └── src/styles/ # globals.css (Tailwind, CSS vars, theme)
│ ├── env/ # Zod environment schemas
│ └── config/ # Shared tsconfig
├── .agents/ # AI agent skills (shadcn, turborepo, etc.)
├── turbo.json # Turborepo pipeline
├── pnpm-workspace.yaml
└── package.json
Naming Conventions
| What | Convention | Example |
|---|---|---|
| Route files | kebab-case.tsx |
tools.date.timezone.tsx |
| Components | kebab-case.tsx |
app-sidebar.tsx |
| Shared UI components | kebab-case.tsx |
button.tsx, combobox.tsx |
Adding a New Tool
- Create route files in
apps/web/src/routes/:tools.foo.tsx # parent layout + landing page tools.foo.bar.tsx # sub-page - Add the
contextbreadcrumb andheadtitle in each route. - Add the tool to the
mainToolsarray inapps/web/src/components/app-sidebar.tsx. - Add a card to the
toolsarray inapps/web/src/routes/index.tsx.
Shared UI Components
All shadcn/ui primitives live in packages/ui and are available via workspace imports:
import { Button } from "@swiss-web/ui/components/button";
import { Calendar } from "@swiss-web/ui/components/calendar";
import { Combobox } from "@swiss-web/ui/components/combobox";
Install new components from the project root:
pnpm dlx shadcn@latest add <component> -c packages/ui
Installed primitives: button, card, calendar, checkbox, combobox, dropdown-menu, input, input-group, label, popover, separator, sheet, sidebar, skeleton, sonner, textarea, tooltip, breadcrumb.
Design Tokens
Edit CSS variables in packages/ui/src/styles/globals.css:
- Colors —
--background,--foreground,--primary,--muted, etc. - Sidebar —
--sidebar,--sidebar-foreground,--sidebar-primary - Border radius —
--radius(default: 0.625rem) - Font — the
--font-sansfamily (Rubik) - Dark mode — class strategy via
next-themes
Available Scripts
| Command | Description |
|---|---|
pnpm run dev |
Start all apps in dev mode |
pnpm run dev:web |
Start only the web app |
pnpm run build |
Production build all packages |
pnpm run check-types |
TypeScript check + Vite build |