Install
$ agentstack add skill-michelve-hugin-cowork-nodejs ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Current Project Context
!`cat package.json 2>/dev/null || echo '{"error": "No package.json found."}'`
Node.js Backend Patterns
When to Use
- Building Express API routes
- Creating middleware
- Configuring Node.js server
- Implementing async/await error handling patterns
- Setting up layered architecture (Controller → Service → Repository)
- Working with Node.js streams or modules
Purpose
Core patterns for building scalable Node.js backend applications with TypeScript, emphasizing clean architecture, error handling, and testability.
When to Use This Skill
- Building Node.js backend services
- Implementing async/await patterns
- Error handling and logging
- Configuration management
- Testing backend code
- Layered architecture (routes → controllers → services → repositories)
Quick Start
Layered Architecture
src/
├── api/
│ ├── routes/ # HTTP route definitions
│ ├── controllers/ # Request/response handling
│ ├── services/ # Business logic
│ └── repositories/ # Data access
├── middleware/ # Express middleware
├── types/ # TypeScript types
├── config/ # Configuration
└── utils/ # Utilities
Flow: Route → Controller → Service → Repository → Database
Async/Await Error Handling
See [resources/async-and-errors.md](resources/async-and-errors.md) for async/await patterns (basic pattern, controller pattern, Promise.all for parallel operations, custom error classes, async error wrapper).
TypeScript Patterns
Request/Response Types
// Request body
interface CreateUserRequest {
email: string;
name: string;
password: string;
}
// Response
interface ApiResponse {
success: boolean;
data?: T;
error?: string;
message?: string;
}
// Usage
async function createUser(
req: Request,
res: Response>,
): Promise {
const { email, name, password } = req.body;
const user = await userService.create({ email, name, password });
res.json({
success: true,
data: user,
});
}
Service Layer Types
interface IUserService {
getById(id: string): Promise;
create(data: CreateUserDto): Promise;
update(id: string, data: UpdateUserDto): Promise;
delete(id: string): Promise;
}
class UserService implements IUserService {
async getById(id: string): Promise {
// Implementation
}
async create(data: CreateUserDto): Promise {
// Implementation
}
async update(id: string, data: UpdateUserDto): Promise {
// Implementation
}
async delete(id: string): Promise {
// Implementation
}
}
Configuration Management
Environment Variables
// config/env.ts
import { z } from "zod";
const envSchema = z.object({
NODE_ENV: z.enum(["development", "production", "test"]),
PORT: z.string().transform(Number),
DATABASE_URL: z.string().url(),
JWT_SECRET: z.string().min(32),
LOG_LEVEL: z.enum(["error", "warn", "info", "debug"]).default("info"),
});
export const env = envSchema.parse(process.env);
Unified Config
// config/index.ts
interface Config {
server: {
port: number;
host: string;
};
database: {
url: string;
};
auth: {
jwtSecret: string;
jwtExpiry: string;
};
}
export const config: Config = {
server: {
port: parseInt(process.env.PORT || "3000"),
host: process.env.HOST || "localhost",
},
database: {
url: process.env.DATABASE_URL || "",
},
auth: {
jwtSecret: process.env.JWT_SECRET || "",
jwtExpiry: process.env.JWT_EXPIRY || "7d",
},
};
Layered Architecture (Detailed)
See [resources/architecture-patterns.md](resources/architecture-patterns.md) for detailed controller, service, and repository layer implementations plus dependency injection patterns.
Error Handling
See [resources/async-and-errors.md](resources/async-and-errors.md) for custom error classes (AppError, NotFoundError, ValidationError) and async error wrapper pattern.
Best Practices
1. Always Use Async/Await
// ✅ Good: async/await
async function getUser(id: string): Promise {
const user = await userRepository.findById(id);
return user;
}
// ❌ Avoid: Promise chains
function getUser(id: string): Promise {
return userRepository.findById(id)
.then(user => user)
.catch(error => throw error);
}
2. Layer Separation
// ✅ Good: Separated layers
// Controller handles HTTP
// Service handles business logic
// Repository handles data access
// ❌ Avoid: Business logic in controllers
class UserController {
async create(req: Request, res: Response) {
// ❌ Don't put business logic here
const hashedPassword = await hash(req.body.password);
const user = await db.user.create({...});
res.json(user);
}
}
3. Type Everything
// ✅ Good: Full type coverage
async function updateUser(id: string, data: UpdateUserDto): Promise {
return userService.update(id, data);
}
// ❌ Avoid: any types
async function updateUser(id: any, data: any): Promise {
return userService.update(id, data);
}
Additional Resources
For more patterns, see:
- [async-and-errors.md](resources/async-and-errors.md) - Advanced error handling
- [testing-guide.md](resources/testing-guide.md) - Comprehensive testing
- [architecture-patterns.md](resources/architecture-patterns.md) - Architecture details
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: michelve
- Source: michelve/hugin-cowork
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.