Project structure

Filenames carry meaning. A file's name gives its route, and its last dotted segment gives its type, so a directory listing already explains the site.

This puts the methodology's explicit file types into practice. Choose roles that make sense in your project.

1. Inspect the project

Look at what pmx init created:

my-site/
├── package.json     pins Core and defines dev, start, check scripts
├── tsconfig.json    types for actions/ and plugins/
├── .gitignore       node_modules, .pathmx, dist, .env
└── paths/
    ├── index.md          the home page and default layout declaration
    ├── site.layout.md   content, reference sidebar, and overlay destinations
    └── site.css         the layout's stylesheet

paths/ is the Source root. Every Markdown file in it is a Source. The starter layout supports opening Sources alongside a page.

2. Name a typed Source

Create paths/notes/energy.note.md:

# Energy notes

Compare how a falling ball and a stretched spring store energy.

Its name follows this pattern:

name[.qualifier...].type.md
energy.note.md        name "energy", type "note"
week-1.draft.lab.md   name "week-1", qualifier "draft", type "lab"
about.md              name "about", type "page"

The last segment before .md is the type. Files with a single segment are the default type, page. Types are open: any word works, and Plugins give particular types behavior.

3. Inspect the routes

Run bun run pmx tree to see routes and types together:

paths/
├── index.md (page · 1 block)
├── site.layout.md (layout · 1 block)
└── notes/
    └── energy.note.md (note · 1 block)

The page is served at /notes/energy.note. Rendered routes include the Source type: about.md has the default type page and renders at /about.page. Requesting /notes/energy.note.md returns the authored Markdown itself.

4. Add a folder page

Create paths/notes/index.md:

# Notes

Read the [energy notes](./energy.note.md).

A folder's index.md is that folder's page, served at /notes. Breadcrumbs and generated links use it automatically.

5. Locate project resources

A project can organize its resources like this:

my-site/
├── package.json     dependencies and pathmx.plugins activation
├── paths/           Sources, assets, stylesheets
├── plugins/         custom or configured Plugins: name.plugin.ts
├── actions/         optional modules imported by Plugins
├── .env             project environment, loaded by the CLI
├── db/   runtime state owned by Plugins, not committed
└── dist/            output of pmx export

The CLI finds package.json from any nested directory and resolves project resources beside it. actions/ is only an organizational choice: register custom Actions explicitly in a repository plugin.

Ready-to-use package Plugins activate through pmx plugins add, which records them in package.json#pathmx.plugins. See package setup.

Do not add id to Source frontmatter. Identity comes from the filename, and pmx lint warns when it finds an ignored override.

Typecheck project code

The generated tsconfig.json extends Core's public configuration:

{
  "extends": "@pathmx/core/tsconfig",
  "include": ["actions/**/*", "plugins/**/*"]
}

Run bun run typecheck from the project directory. The configuration enables strict checking, Bun and DOM types, bundler module resolution, TypeScript import extensions, and React JSX. It also includes PathMX's asset module declarations. It checks code without emitting JavaScript; PathMX builds browser clients itself.

Extend include when code lives elsewhere, such as paths/**/*.tsx for literate components. Keep the inherited files entry so PathMX's declarations remain available, including in a project that has no TypeScript files yet.

Next

Choose a host with How PathMX runs, then Publish.