SMRT Project Requirements
Every SMRT project must meet these requirements to work correctly.
Required Files
1. vitest.config.ts (REQUIRED)
import { defineConfig } from 'vitest/config';
import { smrtVitestPlugin } from '@happyvertical/smrt-vitest';
export default defineConfig({
plugins: [smrtVitestPlugin()],
test: {
globals: true,
environment: 'node',
testTimeout: 60000,
fileParallelism: false,
pool: 'forks',
},
});
Why: The vitest plugin automatically generates manifests and loads cross-package dependencies. Without it, tests will fail with "unregistered class" or "No field metadata found" errors.
Note: do not add maxWorkers — fileParallelism: false already pins the
pool to a single worker and Vitest overrides any user-supplied value. Do not add
singleFork either: it was poolOptions.forks.singleFork in Vitest 3 and does
not exist in Vitest 4, and unknown keys are ignored rather than rejected.
Keep the default isolate: true. Disabling isolation shares one module registry
across test files and makes them order-dependent, which is only worth it for
unusually heavy packages and only after verifying that suite under randomized
file order (--sequence.shuffle.files --sequence.seed=N). If a heavy package
needs relief but depends on per-file isolation, keep isolate: true and raise
the per-fork heap with NODE_OPTIONS=--max-old-space-size=... instead.
2. package.json Dependencies
Required:
@happyvertical/smrt-core- Core framework@happyvertical/smrt-vitest(devDependency) - Test plugintypescript>= 5.0vitest>= 2.0vite>= 5.0
Example:
{
"type": "module",
"dependencies": {
"@happyvertical/smrt-core": "workspace:*"
},
"devDependencies": {
"@happyvertical/smrt-vitest": "workspace:*",
"typescript": "^5.9.3",
"vitest": "^4.0.0",
"vite": "^6.0.0"
}
}
3. tsconfig.json
Required settings:
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"composite": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"declaration": true,
"declarationMap": true,
"outDir": "dist"
}
}
Key requirements:
"module": "ESNext"or"NodeNext"- ESM is required"moduleResolution": "bundler"or"NodeNext"- For proper module resolution"strict": true- Type safety"composite": true- For monorepo packages (enables project references)"experimentalDecorators": true- Required for@smrt()decorator
4. smrt.config.ts (Recommended)
For CLI and database configuration:
import type { SmrtConfig } from '@happyvertical/smrt-config';
export default {
packages: {
cli: {
database: {
type: 'sqlite',
url: './data/app.db'
}
}
}
} satisfies SmrtConfig;
Project Structure
my-smrt-project/
├── src/
│ ├── objects/ # SMRT object definitions
│ │ ├── index.ts # Re-exports all objects
│ │ └── *.ts # Classes with @smrt() decorator
│ └── __tests__/ # Test files
│ └── *.test.ts
├── .smrt/ # Generated (gitignored)
│ └── manifest.json # Auto-generated by vitest plugin
├── package.json
├── tsconfig.json
├── vitest.config.ts # REQUIRED - must include smrtVitestPlugin
└── smrt.config.ts # Optional - CLI/database config
Checklist
Before running tests, verify:
-
vitest.config.tsexists withsmrtVitestPlugin() -
@happyvertical/smrt-vitestin devDependencies -
@happyvertical/smrt-corein dependencies - TypeScript strict mode enabled
- ES modules configured (
"type": "module"in package.json) -
.smrt/added to.gitignore -
experimentalDecoratorsenabled in tsconfig.json
Running Tests
# Correct - vitest plugin handles manifest generation automatically
npx vitest
npx vitest run
npm test
# Deprecated - no longer needed (shows warning but still works)
smrt test
The vitest plugin automatically:
- Generates a manifest from your
src/**/*.tsfiles - Discovers and loads manifests from SMRT peer dependencies
- Registers all classes with the ObjectRegistry
Plugin Options
smrtVitestPlugin({
// Auto-generate manifest (default: true)
generateManifest: true,
// Source patterns to scan (default: ['src/**/*.ts'])
include: ['src/**/*.ts'],
// Patterns to exclude (default: ['**/*.d.ts', '**/node_modules/**', '**/dist/**'])
exclude: ['**/*.d.ts', '**/node_modules/**'],
// Additional packages to load manifests from
packages: ['@my-org/custom-smrt-package'],
// Enable verbose logging
verbose: true,
})
Common Issues
"No field metadata found" Error
Cause: Manifest not generated or vitest plugin not configured.
Fix: Ensure vitest.config.ts includes smrtVitestPlugin().
// vitest.config.ts
import { smrtVitestPlugin } from '@happyvertical/smrt-vitest';
export default defineConfig({
plugins: [smrtVitestPlugin()], // This line is required!
});
"Unregistered class" Error
Cause: Class not decorated with @smrt() or manifest stale.
Fix:
- Add
@smrt()decorator to class:import { SmrtObject, smrt } from '@happyvertical/smrt-core';@smrt() // Required!class MyObject extends SmrtObject {// ...} - Restart vitest (manifest regenerates on startup)
"Cannot find module '@happyvertical/smrt-core'" Error
Cause: Dependencies not installed or package.json misconfigured.
Fix:
- Run
pnpm install(or npm/yarn) - Verify
@happyvertical/smrt-coreis in dependencies - Verify
"type": "module"in package.json
Tests Pass Locally but Fail in CI
Cause: Different database behavior (SQLite vs PostgreSQL).
Fix: Use createIsolatedTestDb for database isolation:
import { createIsolatedTestDb } from '@happyvertical/smrt-vitest';
let db, cleanup;
beforeEach(async () => {
const result = await createIsolatedTestDb({ schema: '...' });
db = result.db;
cleanup = result.cleanup;
});
afterEach(async () => {
await cleanup();
});
Watch Mode Doesn't Pick Up New Classes
Current behavior: The manifest is generated once at vitest startup.
Fix: Restart vitest after adding new classes or fields.
Future enhancement: Watch mode manifest refresh is planned (see GitHub issues).
Migration from smrt test
If your project previously used smrt test:
- Add vitest.config.ts with
smrtVitestPlugin()if not already present - Remove
smrt testorsmrt generate:testfrom npm scripts (optional - still works) - Update npm test script to use
vitest rundirectly:{"scripts": {"test": "vitest run"}} - Add
.smrt/to.gitignoreif not present
The smrt test command still works but shows a deprecation warning.
Related Documentation
- packages/vitest/AGENTS.md - Vitest plugin details
- packages/core/AGENTS.md - Core framework reference
- TESTING_STANDARD.md - Testing requirements