# Code Organization

> Repo file-organization convention for TypeScript projects. ALWAYS use this when creating new files or deciding where code goes — types, schemas, validation, utility/helper functions, constants, enums, and config literals each belong in their own dedicated folder, not inline next to feature code or dumped in one grab-bag file. Use whenever you add a type/interface, a validation schema, a util/helper, a constant, or are asked where something should live, how to structure the repo, or to organize/refactor file layout.

- Skill: `usenotra/code-organization` (Agent Skill)
- Install (CLI): `npx skillmds@latest add usenotra/code-organization`
- Raw SKILL.md: https://api.skillmd.com/api/skills/usenotra/code-organization/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: usenotra (https://skillmd.com/u/usenotra)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/usenotra/code-organization

---


# code-organization

Where each kind of code goes. Apply this **every time** you create a file or
add a type, schema, helper, or constant. Don't inline them next to feature
code and don't pile unrelated things into one file.

## Layout

Each category gets its **own dedicated folder**. Files inside a folder are
grouped by domain (e.g. `user`, `post`), not by individual symbol.

```
src/
  types/        type & interface definitions        types/user.ts
  schemas/      validation schemas (zod, yup, etc.) schemas/user.ts
  utils/        helper / utility functions          utils/format.ts
  constants/    constant values, enums, config      constants/routes.ts
```

## Rules

1. **One folder per category** — `types/`, `schemas/`, `utils/`, `constants/`.
   A new type goes in `types/`, never inline in the file that uses it or
   alongside a component.

2. **Group files by domain inside a folder.** All user-related types live in
   `types/user.ts`; all user-related constants in `constants/user.ts`. Split a
   file once it covers clearly separate domains — not per symbol.

3. **Functions get their own file.** A reusable helper lives in `utils/` in a
   file named for what it does (`utils/format.ts`, `utils/slugify.ts`). Keep one
   focused concern per file; don't accumulate a `utils/index.ts` junk drawer.

4. **No barrel files.** Do **not** add `index.ts` re-export barrels. Import
   directly from the specific file:

   ```ts
   import { formatDate } from "@/utils/format";   // ✓
   import { formatDate } from "@/utils";           // ✗ no barrel
   ```

   This keeps imports explicit and avoids circular-import and tree-shaking
   surprises.

5. **Types vs schemas are separate concerns.** `types/` holds pure TypeScript
   type/interface declarations. `schemas/` holds runtime validation schemas. If
   a type is derived from a schema, infer it in `types/` and import the schema —
   keep the validator in `schemas/`.

## Where does it go?

| You're adding… | Folder | Example file |
|---|---|---|
| `type` / `interface` | `types/` | `types/user.ts` |
| validation / parse schema | `schemas/` | `schemas/user.ts` |
| pure helper function | `utils/` | `utils/format.ts` |
| constant, enum, config literal | `constants/` | `constants/routes.ts` |
| React component, route, feature code | feature dir | `user/profile.tsx` |

## Gotchas

- **A one-off type still goes in `types/`.** "It's only used here" is not a
  reason to inline it — consistency is the point. The next person looks in
  `types/` first.
- **Don't create a barrel to shorten imports.** Rule 4 is deliberate; longer
  import paths are the trade-off, and they're worth it.
- **`utils/` is not a dumping ground.** If a helper is specific to one feature
  and never reused, it can live with that feature — `utils/` is for genuinely
  shared helpers.
- **Match the existing folder names in the repo** if it already has `types/` /
  `lib/` / `helpers/`. Follow what's there rather than introducing a parallel
  set of folders.

