Package Exports
- @zerooneit/expressive-tea
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@zerooneit/expressive-tea) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Expressive Tea
A modern, TypeScript-first framework for building scalable Node.js applications
Clean architecture β’ Dependency Injection β’ Decorator-driven β’ Express-powered
π Documentation
Β·
π Live Demo
Β·
π Report Bug
Β·
π‘ Request Feature
[!IMPORTANT]
π¦ Package Renamed:
@expressive-tea/coreExpressive Tea has a new home on npm! Starting with v2.0.0, install using:
npm install @expressive-tea/coreLegacy package
@zerooneit/expressive-teawill be maintained until April 30, 2026 for security patches only. Please migrate to@expressive-tea/coreas soon as possible.Why the change?
- β¨ Better namespace organization (
@expressive-tea/*)- π Community-focused ownership
- π Clearer project identity
Migration is simple: Just update your
package.jsonand imports remain the same!- "dependencies": { "@zerooneit/expressive-tea": "^1.2.0" } + "dependencies": { "@expressive-tea/core": "^2.0.0" }
[!CAUTION]
β οΈ CRITICAL: v1.x Security Notice
All versions 1.x are DEPRECATED and UNSUPPORTED as of January 27, 2026.
v1.3.x Beta - π΄ CRITICAL SECURITY VULNERABILITY - DO NOT USE
Contains critical cryptography flaws in Teapot/Teacup gateway. If you're using this, STOP IMMEDIATELY and upgrade to v2.0.0.v1.2.x Production - π‘ No crypto issues, but deprecated (InversifyJS v6 EOL)
π Upgrade to v2.0.0 NOW - See Migration Guide
β‘ Quick Start
# Install the new package
npm install @expressive-tea/core
# Or with yarn
yarn add @expressive-tea/coreimport { ServerSettings, Route, Get, Boot } from '@expressive-tea/core';
@ServerSettings({ port: 3000 })
class App extends Boot {}
@Route('/hello')
class HelloController {
@Get('/')
sayHello() {
return { message: 'Hello, World! π΅' };
}
}
new App().start();
// π Server running on http://localhost:3000Try it live on CodeSandbox β
π― Why Expressive Tea?
The Problem
Building Node.js applications is powerful, but messy. You get a blank canvas with Expressβno structure, no conventions, just middleware chaos. Sound familiar?
The Solution
Expressive Tea brings the elegance of modern frameworks to Node.js, without the bloat. Think NestJS simplicity meets Express flexibility.
π What Makes It Special
| Feature | What You Get |
|---|---|
| π¨ Clean Architecture | Decorators organize your code beautifullyβno more spaghetti routes |
| π Plugin Everything | Share database configs, auth, websockets across projects |
| π Smart DI | Singleton, Transient, Scoped servicesβInversifyJS under the hood |
| π‘οΈ Type-Safe | Full TypeScript strict modeβcatch bugs before they ship |
| π Secure by Default | AES-256-GCM + HKDF crypto, built-in security best practices |
| β‘ Production Ready | 92%+ test coverage, battle-tested in real applications |
| π― Express Compatible | Use ANY Express middlewareβgradual migration friendly |
| π¦ Zero Lock-in | BYOA (Bring Your Own Architecture)βwe don't force opinions |
π What's New in v2.0
Major security and architecture improvements!
+ β
Security: Fixed critical crypto vulnerabilities (AES-256-GCM + HKDF)
+ β
Type Safety: Full TypeScript strict mode support
+ β
DI: Scoped dependency injection (Singleton/Transient/Scoped)
+ β
Health Checks: Built-in health endpoints for Kubernetes/monitoring
+ β
Environment: .env file support with @Env decorator
+ β
Performance: Native utilities, removed lodash dependencies
+ β
ESLint: Migrated to ESLint v9 flat config
+ β
Quality: 95%+ coverage, all tests passingβ οΈ Breaking Changes:
- Cryptography format changed (must re-encrypt data)
- TypeScript strict mode enabled
- Node.js 20+ required (Node.js 18 reached EOL April 2025)
- Express 5.x required
- ESLint v9 (flat config)
π Full Changelog β’ π Migration Guide
π‘ Features That'll Make You Smile
π¨ Decorator-Driven Development
@Route('/api/users')
class UserController {
@Get('/:id')
async getUser(@Param('id') id: string) {
return this.userService.findById(id);
}
@Post('/')
async createUser(@Body() data: CreateUserDto) {
return this.userService.create(data);
}
}π Pluggable Architecture
import { AuthPlugin } from '@my-org/auth-plugin';
import { DatabasePlugin } from '@my-org/db-plugin';
@ServerSettings({
port: 3000,
plugins: [AuthPlugin, DatabasePlugin]
})
class App extends Boot {}π Dependency Injection
@injectable()
class UserService {
constructor(
@inject(TYPES.Database) private db: Database,
@inject(TYPES.Logger) private logger: Logger
) {}
}π― Type-Safe Everything
// Generics everywhere
class ApiResponse<T> {
constructor(
public data: T,
public status: number
) {}
}
@Get('/users')
getUsers(): ApiResponse<User[]> {
return new ApiResponse(users, 200);
}π₯ Built-in Health Checks
@HealthCheck({
checks: [
{
name: 'database',
check: async () => {
const isConnected = await db.ping();
return { status: isConnected ? 'pass' : 'fail' };
},
critical: true, // Blocks readiness probe if fails
timeout: 5000
}
]
})
class App extends Boot {}
// Endpoints:
// GET /health - Detailed health status
// GET /health/live - Liveness probe (K8s)
// GET /health/ready - Readiness probe (K8s)π Environment Variable Support
// Load from .env files
@Env({ path: '.env', required: ['DATABASE_URL', 'API_KEY'] })
@Env({ path: '.env.local', override: true, silent: true })
class App extends Boot {}
// In your .env:
// DATABASE_URL=postgres://localhost:5432/mydb
// API_KEY="secret-key"π― Type-Safe Environment Variables (v2.0.1+)
import { z } from 'zod';
const EnvSchema = z.object({
PORT: z.string().transform(Number),
DATABASE_URL: z.string().url(),
API_KEY: z.string().min(32)
});
type Env = z.infer<typeof EnvSchema>;
@Env<Env>({
transform: (env) => EnvSchema.parse(env),
onTransformError: 'throw' // Fail fast on invalid env
})
class App extends Boot {
constructor() {
super();
const env = Settings.getInstance().getEnv<Env>();
console.log(env.PORT); // Type: number (validated!)
}
}π Configuration Files (v2.0.1+)
# .expressive-tea.yaml (YAML support!)
port: 3000
securePort: 4443
database:
host: localhost
port: 5432
# Comments supported!
cache:
enabled: true
ttl: 3600File Priority: .expressive-tea.yaml > .expressive-tea.yml > .expressive-tea (JSON)
π¦ Installation & Setup
Prerequisites
- Node.js β₯ 20.0.0
- TypeScript β₯ 5.0.0
- Express β₯ 5.0.0
Note: Node.js 18 support was dropped in v2.0.0 as it reached End-of-Life in April 2025. We recommend using Node.js 20 LTS or Node.js 22 for the best experience and security updates.
Configure TypeScript
{
"compilerOptions": {
"target": "ES2017",
"module": "commonjs",
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
// Recommended for maximum safety
"strict": true,
"strictNullChecks": true,
"noImplicitAny": true
}
}Install
# npm
npm install @expressive-tea/core reflect-metadata
# yarn
yarn add @expressive-tea/core reflect-metadataLocal staging with Verdaccio
If you want to test publishing locally before pushing to the public registry, use a local Verdaccio instance as a staging registry.
Quick steps:
- Start Verdaccio (Docker):
docker run -d --rm --name verdaccio-expressive-tea -p 4873:4873 verdaccio/verdaccio:latest- Point npm to local registry and publish:
# point npm to local registry
npm set registry http://localhost:4873
# publish (from package root)
npm publish --registry http://localhost:4873
# restore default registry
npm set registry https://registry.npmjs.org/- Optional: Use the repo-provided Verdaccio config for deterministic behavior:
docker run -d --rm --name verdaccio-expressive-tea -p 4873:4873 \
-v $(pwd)/.docs/verdaccio/config.yaml:/verdaccio/conf/config.yaml \
verdaccio/verdaccio:latestNotes:
- Default URL: http://localhost:4873
- Container name: verdaccio-expressive-tea (the agent checks for this name before starting a new container)
- Anonymous publishing is enabled in the example config (local only). Do not expose to public networks.
- The config permits overwriting the same package version for easy iterative testing.
Your First App
1. Create your server:
// server.ts
import 'reflect-metadata';
import { ServerSettings, Boot } from '@expressive-tea/core';
@ServerSettings({
port: 3000,
controllers: [HelloController]
})
class MyApp extends Boot {}
export default MyApp;2. Add a controller:
// controllers/hello.controller.ts
import { Route, Get } from '@expressive-tea/core';
@Route('/hello')
export class HelloController {
@Get('/')
sayHello() {
return { message: 'Hello, Expressive Tea! π΅' };
}
}3. Start it up:
// main.ts
import MyApp from './server';
const app = new MyApp();
app.start().then(() => {
console.log('π Server is running!');
});π Learn More
π Documentation
- Complete Guide - Full documentation
- API Reference - Complete API docs
- Examples - Sample projects
π v2.0.1 Features
- Configuration Files Guide - YAML/JSON config support
- Environment Variables Guide - Type-safe env with Zod
π Migration & Upgrading
- Migration Guide v1 β v2 - Step-by-step upgrade
- Release Notes v2.0 - What's new
- Deprecation Notice - v1.x timeline
π‘οΈ Security
- Security Policy - Vulnerability reporting
- Changelog - Version history
π€ Contributing
We love contributions! Whether it's bug fixes, features, or docs.
Quick links:
- Contributing Guide - How to contribute
- Code of Conduct - Community guidelines
- Issues - Report bugs or request features
# Get started
git clone https://github.com/Expressive-Tea/expresive-tea.git
cd expresive-tea
yarn install
yarn testπ€ AI-Assisted Development & Vibe Coding
We welcome AI-assisted contributions! Whether you're using GitHub Copilot, Cursor, Claude, or other AI coding assistants, we embrace the future of collaborative development.
β οΈ IMPORTANT: AI-Generated Code Requirements
If you're using AI tools for code generation, you MUST:
π Follow Repository Guidelines
π¨βπ» Human Review is MANDATORY
- β All AI-generated code MUST be reviewed by a human developer before creating a pull request
- β Understand the code completelyβdon't submit code you can't explain
- β Test thoroughly (aim for 95%+ coverage)
- β Verify the code follows our architectural patterns and best practices
β Quality Standards
- β
All tests must pass (
yarn test) - β
Linting must pass (
yarn linter:ci) - β
TypeScript must compile without errors (
yarn build) - β Code must match our existing patterns and conventions
- β Documentation must be updated (JSDoc, README, CHANGELOG)
- β
All tests must pass (
π PR Transparency
- β Disclose AI assistance in your pull request description
- β Example: "This PR was developed with assistance from Claude/Copilot/Cursor"
- β Highlight any sections that were fully AI-generated for extra review
Why These Rules?
- π‘οΈ Quality Assurance - AI can make subtle mistakes humans catch
- π― Consistency - Ensures code matches our architectural vision
- π Knowledge Transfer - Reviewers understand your contribution
- π Security - Prevents AI from introducing vulnerabilities
- π€ Collaboration - Maintains clear communication in the codebase
Vibe Coding Best Practices:
// β
GOOD: AI-generated, reviewed, and refined by human
@Route('/api/users')
class UserController {
@Get('/:id')
async getUser(@Param('id') id: string): Promise<User> {
// Human: Added validation per AGENTS.md security guidelines
if (!id || !validator.isUUID(id)) {
throw new BadRequestException('Invalid user ID');
}
return this.userService.findById(id);
}
}
// β BAD: AI-generated, unreviewed, missing error handling
@Route('/api/users')
class UserController {
@Get('/:id')
async getUser(@Param('id') id: string) {
return this.userService.findById(id); // What if id is invalid?
}
}π Required Reading for AI-Assisted Development:
AGENTS.md- Repository-specific rules for AI agentsCLAUDE.md- Claude AI coding guidelinesCONTRIBUTING.md- General contribution guide.prettierrc- Code formatting ruleseslint.config.js- Linting configuration
Questions? Ask in GitHub Discussions before submitting AI-generated code.
π¬ Community & Support
Get Help
- π Documentation
- π¬ Gitter Chat
- π§ Email Support
- π GitHub Issues
- π Stack Overflow - Use tag
expressive-tea
Stay Connected
- π¦ Twitter: @expressive_tea
- π§ Email: support@expressive-tea.io
- π¨βπ» Author: Diego Resendez
π Built With
| Technology | Purpose |
|---|---|
| Express | Fast, unopinionated web framework |
| TypeScript | Type-safe JavaScript |
| InversifyJS | Powerful dependency injection |
| Reflect Metadata | Decorator metadata support |
π Sponsors
Building Expressive Tea takes time and dedication. If this project helps you, consider sponsoring!
Principal Sponsor:
Interested in sponsoring? Contact projects@zero-oneit.com
π License
Apache-2.0 License - see LICENSE file for details
π Versioning
We use Semantic Versioning (SemVer). See tags for available versions.
π₯ Contributors
Lead Developer: Diego Resendez
See all contributors who've helped shape Expressive Tea.
β€οΈ Credits
Logo and banner designed by Freepik
Made with β and π΅ by the Expressive Tea Team
Start brewing better Node.js apps today!