One directory lives outside
app/ and still shapes it: .fymo/templates/ holds project-local overrides for the generator templates. A file there at the same relative path as a packaged template wins over it, so a team’s conventions ride along in the repo. fymo generate templates publishes the packaged tree there for editing; see Generators.
Task registries
Files underapp/jobs are meant to stay thin. Think of it as a handful of submittable entry points, not a place where implementation piles up.
Every top-level function without a leading underscore becomes a submittable task automatically. Mark the ones you mean as entry points with @task so that’s explicit, and prefix any helper you don’t want exposed with an underscore.
Safety net, not a trap
Fymo watches for a couple of easy mix-ups so you don’t have to. Say a Svelte file ends up in the controllers folder, or a Python file ends up in templates or components. The build catches it immediately. Bothfymo build and fymo dev will tell you exactly what’s misplaced, right when you save.
Without this check, Python would simply never import a stray
.svelte file, and esbuild would never bundle a stray .py file. You’d just have a feature that quietly does nothing. Hearing about it the moment you save beats hunting for it later.app/assets, imported explicitly from a layout, like import '../assets/app.css' in app/templates/_layout.svelte. A loose .css file anywhere under app/templates fails the build with stylesheets live in app/assets/, found <path>. <style> blocks inside a .svelte file are untouched, that’s Svelte’s own component styling and none of this check’s business.
Coming from an older Fymo project,
app/templates/_global.css used to be picked up automatically. It isn’t anymore. A project still shipping that exact file fails the build with the exact fix:Where identity lives
app/auth is where @identify resolvers decide who’s making a request. Fymo auto-discovers every module there the same way it discovers app/remote, just through a separate glob, one is never mistaken for the other.
Run fymo generate auth to scaffold a resolver and the login flow around it. Delete the whole directory and identity resolution turns off, nothing else needs to change.
That’s the placement story. For resolvers, current_uid(), route guards, and testing with signed_in(), see Authentication.
One line, three homes
If a file’s home is ever unclear, one line covers most of it. In git and compiled with the app, it belongs inapp/assets. In git and served exactly as it sits on disk, it belongs in app/static. Created after the app is deployed, it belongs in storage, not in git at all. See Storage and media for that last one.