
Research
/Security News
Miasma Mini Shai-Hulud Hits ImmobiliareLabs npm Packages
Miasma Mini Shai-Hulud hits @immobiliarelabs Backstage plugins, targeting GitLab and LDAP auth packages on npm.
🚀 Supercharge your Hono apps with decorators and dependency injection.
Smart, lightweight DI & decorator toolkit for Hono. Build enterprise-grade APIs with elegance and robust security.
BarqApi supercharges your Hono experience with decorator-driven development, dependency injection, and powerful guard systems. Create maintainable, testable APIs with minimal boilerplate while leveraging Hono's blazing-fast performance.
Using npm:
npm install BarqApi hono reflect-metadata
Using yarn:
yarn add BarqApi hono reflect-metadata
Using bun:
bun add BarqApi hono reflect-metadata
Configure TypeScript (tsconfig.json):
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}
🛡️ Powerful Guards System
🎯 Smart Dependency Injection
🔌 Type-Safe Controllers
🚀 Zero-Config Response Handling
🔍 Intelligent Request Parsing
⚡ Lightweight & Fast
import { Hono } from 'hono';
import { Controller, Get, Post, Injectable, Router, Guards, HttpError } from 'BarqApi';
// Simple auth guard
const authGuard = async (header) => {
const token = header('authorization');
if (!token) {
return false; // Will return 401 Unauthorized
}
return true;
};
// Simple role guard
const adminGuard = async (header) => {
const role = header('x-role');
if (role !== 'admin') {
throw new HttpError(403, 'Admin access required');
}
return true;
};
@Injectable()
class UserService {
getUsers() {
return [
{ id: 1, name: 'John' },
{ id: 2, name: 'Jane' }
];
}
}
@Controller('/users')
@Guards(authGuard) // Apply auth to all routes
class UserController {
constructor(private userService: UserService) {}
@Get()
@Guards(adminGuard) // Stack guards - requires both auth and admin
async getUsers() {
return {
data: this.userService.getUsers()
};
}
@Get('/:id')
async getUser(params) {
const id = params.id;
const users = this.userService.getUsers();
const user = users.find(u => u.id === parseInt(id));
if (!user) {
throw new HttpError(404, 'User not found');
}
return { data: user };
}
@Post()
async createUser(body, header) {
const role = header('x-role');
return {
status: 201,
data: { created: true, role }
};
}
}
// Automatically creates a Hono app and starts a server on the specified port
await Server({ port: 3000 });
The server automatically detects the runtime environment:
Guards are just async functions that return true or false:
// Basic auth guard
const authGuard = async (header) => {
return header('authorization') ? true : false;
};
// Guard with custom error
const adminGuard = async (header) => {
if (header('x-role') !== 'admin') {
throw new HttpError(403, 'Admin only');
}
return true;
};
// Guard using multiple parameters
const validateGuard = async (body, header) => {
if (!body.name) {
throw new HttpError(400, 'Name required');
}
if (!header('x-api-key')) {
return false; // 401 Unauthorized
}
return true;
};
Using guards in controllers:
@Controller('/api')
@Guards(authGuard) // Controller-level guard
class ApiController {
@Post('/admin')
@Guards(adminGuard) // Route-level guard
async adminOnly(body) {
return { status: 'success' };
}
}
The DI system supports different instance lifecycles:
// Singleton (default) - one instance per application
@Injectable()
class ConfigService {}
// Request-scoped - new instance per request
@Injectable({ scope: Scope.REQUEST })
class RequestLogger {}
// Transient - new instance every time
@Injectable({ scope: Scope.TRANSIENT })
class UniqueIDGenerator {}
// Service shorthand
@Service()
class UserService {}
// Repository shorthand
@Repository()
class UserRepository {}
// Component shorthand
@Component()
class EmailComponent {}
All these decorators automatically register the class with the DI container.
// Custom error with status
throw new HttpError(400, 'Invalid input');
// Error with code
throw new HttpError(403, 'Not allowed', 'FORBIDDEN');
// Pre-defined error types
HttpError.badRequest('Invalid data');
HttpError.unauthorized('Login required');
HttpError.forbidden('Admin only');
HttpError.notFound('User not found');
HttpError.internal('Something went wrong');
Both guards and controllers can access these parameters by name:
async function handler(
// URL and Route Information
params, // URL parameters
query, // Single query parameters
queries, // Multiple query parameters
path, // Request path
url, // Full URL
routePath, // Matched route path
matchedRoutes, // All matched routes
routeIndex, // Current route index
method, // HTTP method
// Request Data
body, // Parsed request body
header, // Function to get header value
headers, // All headers
// Parsing Methods
json, // Function to parse body as JSON
text, // Function to get body as text
arrayBuffer, // Function to get body as ArrayBuffer
blob, // Function to get body as Blob
formData, // Function to parse form data
// Validation
valid, // Request validation function
// Context
c, // Hono context (also available as 'ctx' or 'context')
) {
// Use only the parameters you need
}
Examples of using different parameters:
@Controller('/api')
class ApiController {
// Basic URL parameters
@Get('/users/:id')
async getUser(params) {
return { userId: params.id };
}
// Query parameters
@Get('/search')
async search(query, queries) {
// Single value: ?tag=node
const tag = query.tag;
// Multiple values: ?tags=node&tags=javascript
const allTags = queries().tags;
return { tag, allTags };
}
// Request body with validation
@Post('/data')
async createData(body, valid) {
const isValid = valid((data) => {
return data.name && data.email;
});
if (!isValid) {
throw new HttpError(400, 'Invalid data');
}
return { created: body };
}
}
The framework automatically handles different types of responses:
// JSON Response (Default)
return { data: { id: 1, name: 'Test' } };
// Empty Response (204 No Content)
return null; // or undefined
// Text Response
return 'Hello World'; // Content-Type: text/plain
// HTML Response
return '<h1>Hello World</h1>'; // Content-Type: text/html
// Custom Status Code
return {
status: 201,
data: { created: true }
};
// Redirect Response
return {
redirect: '/new-location',
status: 302 // Optional, defaults to 302
};
// Stream Response
return new ReadableStream({
start(controller) {
controller.enqueue('Hello');
controller.enqueue(' World');
controller.close();
}
});
Response with Headers:
@Get('/with-headers')
async withHeaders() {
return {
data: { success: true },
headers: {
'X-Custom-Header': 'value',
'Cache-Control': 'max-age=3600'
}
};
}
The framework automatically parses request bodies based on Content-Type header:
@Controller('/api')
class ApiController {
// Automatic JSON parsing
@Post('/json')
async handleJson(body) {
// Content-Type: application/json
// Body is automatically parsed as JSON
return { received: body };
}
// Form data parsing
@Post('/form')
async handleForm(body) {
// Content-Type: multipart/form-data
// or application/x-www-form-urlencoded
// Body is automatically parsed as form data
return { received: body };
}
// Text content
@Post('/text')
async handleText(body) {
// Content-Type: text/plain
// Body is received as string
return { received: body };
}
}
// Test a guard
test('auth guard', async () => {
const header = (name) => name === 'authorization' ? 'Bearer token' : null;
const result = await authGuard(header);
expect(result).toBe(true);
});
// Test a controller
test('get user', async () => {
const params = { id: '1' };
const result = await controller.getUser(params);
expect(result.data.id).toBe(1);
});
Contributions are welcome! Check back soon for contribution guidelines.
This project is licensed under the MIT License - see the LICENSE file for details.
Special thanks to the Hono team for creating an amazing foundation for this project.
FAQs
🚀 Supercharge your Hono apps with decorators and dependency injection.
The npm package barqapi receives a total of 0 weekly downloads. As such, barqapi popularity was classified as not popular.
We found that barqapi demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
/Security News
Miasma Mini Shai-Hulud hits @immobiliarelabs Backstage plugins, targeting GitLab and LDAP auth packages on npm.

Security News
Rolldown paused Rust React Compiler integration after a 5MB binary size increase raised concerns about shipping React-specific code to all Vite users.

Security News
/Research
Mini Shai-Hulud expands into the Go ecosystem after hitting LeoPlatform npm packages and targeting GitHub Actions workflows.