File Structure
Vla doesn’t enforce a specific file structure. You’re free to organize your code however you like. However, we recommend aligning your file structure with how Vla structures your code.
This page provides recommendations based on your app’s size and complexity.
Action Files in your Presentation Layer
Section titled “Action Files in your Presentation Layer”Colocate Actions in your presentation layer (next to your UI components) in a separate file. Create a data.ts file for each group of files, which belong together. This file contains one or more Vla Actions, but no other layers (like Services, Repos or Resources).
Directorysrc/
Directoryapp/ Presentation Layer
Directoryposts/
- data.ts
- page.ts
Directory[slug]/
- page.ts
Directoryauthors/
- data.ts
- page.ts
Directory[user]/
- data.ts
- page.ts
Directorycomponents/ Component Library
- …
Directorydata/ Data Layer
- users.ts
- posts.ts
- db.ts
- kernel.ts
Think of each data.ts file like it defines a module boundary in your presentation layer:
- Files inside a folder should only import from their closest
data.ts. - Keep your
componentsdata-free, as a collection of reusable UI components which don’t fetch data from the data layer. - You can also choose a different file name, like
actions.ts.
For example, using the file structure from above:
posts/page.tsand/posts/[slug]/page.tswould only import fromposts/data.ts. They would not import fromauthors/.authors/page.tswould only import fromauthors/data.ts, and not fromposts/data.tsorauthors/[users]/data.ts.authors/[user]/page.tswould only import fromauthors/[user]/data.ts, and not fromposts/data.tsorauthors/data.ts.
File per Model
Section titled “File per Model”For small apps or prototypes, keep it simple. A handful of files in a single folder is often enough.
Directorysrc/
Directoryapp/ Your framework’s routes
- …
Directorydata/ Data Layer
- users.ts Services and Repos
- posts.ts Services and Repos
- db.ts Resource
- kernel.ts Kernel setup
Layer suffixes
Section titled “Layer suffixes”To split model files into smaller files, you create a file for each layer and give them a suffix, like .service.ts and .repo.ts.
Directorysrc/
Directoryapp/
- …
Directorydata/
Directoryresources/
- db.ts
- redis.ts
- posts.repo.ts
- posts.service.ts
- users.repo.ts
- users.service.ts
Folder per Model
Section titled “Folder per Model”You can additionally group services and repos by their resource. This is especially helpful if you have multiple services for a model.
Directorysrc/
Directoryapp/
- …
Directorydata/
Directoryresources/
- db.ts
- redis.ts
Directoryposts/
- posts.repo.ts
- posts.service.ts
Directoryusers/
- users.repo.ts
- users.service.ts
- authors.service.ts
Folder per Module
Section titled “Folder per Module”For large apps or teams, organize by modules to separate domains. Each module has its own directory with its own structure inside.
Directorysrc/
Directoryapp/
- …
Directorydata/
- kernel.ts
Directoryresources/
- db.ts
- redis.ts
Directoryusers/
- user.facade.ts Public API for other modules
- user.module.ts
- user.repo.ts
- user.service.ts
Directorybilling/
- billing.facade.ts Public API for other modules
- billing.module.ts
- invoice.repo.ts
- invoice.service.ts
- subscription.repo.ts
- subscription.service.ts
Directoryanalytics/
- analytics.facade.ts Public API for other modules
- analytics.module.ts
- analytics.repo.ts
- analytics.service.ts
Module Growth Patterns
Section titled “Module Growth Patterns”As a module grows, you can further organize it internally.
Small Module
Section titled “Small Module”Keep everything flat within the module directory.
Directorydata/
Directoryusers/
- user.facade.ts
- user.module.ts
- user.repo.ts
- user.service.ts
Group by Model
Section titled “Group by Model”Group by model when the module has multiple models.
Directorydata/
Directorybilling/
- billing.module.ts
- billing.facade.ts
Directoryinvoice/
- invoice.repo.ts
- invoice.service.ts
Directorysubscription/
- subscription.repo.ts
- subscription.service.ts
Directorypayment/
- payment.repo.ts
- payment.service.ts
General Guidelines
Section titled “General Guidelines”Keep Resources Global
Section titled “Keep Resources Global”Resources like database clients are typically shared across modules, so keep them in a shared location.
Directorydata/
Directoryresources/
- db.ts
- redis.ts
- s3.ts
Directoryusers/
- …
Directorybilling/
- …
Migration Path
Section titled “Migration Path”You don’t need to choose the “perfect” structure upfront. Start simple and evolve:
- Start small - Single file or flat structure
- Split when needed - Break out files as they grow
- Group when clear - Add folders when grouping becomes obvious
- Modules when scaling - Introduce modules when domains become distinct