npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@struktos/core

v1.0.0

Published

Enterprise-grade Node.js platform with ASP.NET Core-inspired architecture, Go-style context propagation, and high-performance infrastructure

Readme

@struktos/core v1.0.0

Enterprise-grade Node.js platform with ASP.NET Core-inspired architecture

npm version License: MIT

🎯 What's New in v1.0.0

Version 1.0.0 establishes Struktos.js as a standalone platform with its own request processing pipeline, inspired by ASP.NET Core architecture.

Key Features

  • StruktosApp - Application entry point with fluent API
  • IStruktosMiddleware - ASP.NET Core-style middleware pipeline
  • IExceptionFilter - NestJS/ASP.NET-style exception handling
  • IAdapter - Framework/protocol abstraction (Express, Fastify, gRPC, etc.)
  • IHost - Application lifecycle and hosting management
  • RequestContext - Go-style context propagation (enhanced)
  • Built-in Exceptions - HTTP exceptions with proper typing
  • Pipeline Utilities - Composition, branching, retry, timeout

📦 Installation

npm install @struktos/core

🚀 Quick Start

import { 
  StruktosApp, 
  createMiddleware,
  BadRequestException 
} from '@struktos/core';
import { createExpressAdapter } from '@struktos/adapter-express';

// Create application
const app = StruktosApp.create({ name: 'my-api' });

// Add middleware
app.use(async (ctx, next) => {
  console.log(`${ctx.request.method} ${ctx.request.path}`);
  await next();
});

// Add route handler
app.use(async (ctx, next) => {
  if (ctx.request.path === '/hello') {
    ctx.response.body = { message: 'Hello, World!' };
    return;
  }
  await next();
});

// Start with Express adapter
const adapter = createExpressAdapter();
await app.listen(adapter, 3000);

📖 Core Concepts

StruktosApp

The main application class - your entry point for building Struktos applications.

const app = StruktosApp.create({
  name: 'my-app',
  port: 3000,
  gracefulShutdown: true,
  useDefaultErrorHandler: true,
});

// Add middleware
app.use(loggingMiddleware);
app.use(authMiddleware);
app.use(routerMiddleware);

// Add exception filters
app.useExceptionFilter(new ValidationExceptionFilter());

// Start
await app.listen(adapter, 3000);

IStruktosMiddleware

ASP.NET Core-inspired middleware with invoke(ctx, next) pattern.

import { IStruktosMiddleware, MiddlewareContext, NextFunction } from '@struktos/core';

class LoggingMiddleware implements IStruktosMiddleware {
  async invoke(ctx: MiddlewareContext, next: NextFunction): Promise<void> {
    const start = Date.now();
    console.log(`→ ${ctx.request.method} ${ctx.request.path}`);
    
    await next(); // Call next middleware
    
    const duration = Date.now() - start;
    console.log(`← ${ctx.response.status} (${duration}ms)`);
  }
}

// Or use functional style
const loggingMiddleware = createMiddleware(async (ctx, next) => {
  console.log(`${ctx.request.method} ${ctx.request.path}`);
  await next();
});

IExceptionFilter

Handle exceptions and transform them into responses.

import { 
  IExceptionFilter, 
  ExceptionContext, 
  StruktosResponse,
  HttpException 
} from '@struktos/core';

class CustomExceptionFilter implements IExceptionFilter {
  async catch(ctx: ExceptionContext): Promise<StruktosResponse> {
    const { error, context, path, timestamp } = ctx;
    
    if (error instanceof HttpException) {
      return {
        status: error.statusCode,
        headers: { 'Content-Type': 'application/json' },
        body: {
          error: error.name,
          message: error.message,
          traceId: context.get('traceId'),
          timestamp: timestamp.toISOString(),
          path,
        },
      };
    }
    
    throw error; // Pass to next filter
  }
}

Built-in Exceptions

import {
  BadRequestException,
  UnauthorizedException,
  ForbiddenException,
  NotFoundException,
  ConflictException,
  ValidationException,
  TooManyRequestsException,
  InternalServerException,
} from '@struktos/core';

// Usage
throw new BadRequestException('Invalid input');
throw new NotFoundException('User not found');
throw new ValidationException('Validation failed', {
  email: ['Invalid email format'],
  password: ['Password too short'],
});

IAdapter

Abstract interface for framework/protocol adapters.

interface IAdapter {
  readonly name: string;
  readonly protocol: ProtocolType;
  
  init(middlewares: IStruktosMiddleware[]): Promise<void>;
  start(port?: number, host?: string): Promise<ServerInfo>;
  stop(): Promise<void>;
  isRunning(): boolean;
  
  transformRequest(raw: any): StruktosRequest;
  transformResponse(response: StruktosResponse, raw: any): void;
  createContext(raw: any): MiddlewareContext;
}

IHost

Multi-adapter hosting for microservices.

import { createHost, StruktosHost } from '@struktos/core';

const host = createHost({
  name: 'microservice',
  gracefulShutdown: true,
  shutdownTimeout: 30000,
});

host.addAdapter(httpAdapter);
host.addAdapter(grpcAdapter);
host.addBackgroundService(healthCheckService);

await host.start();

Pipeline Utilities

import { 
  createPipeline, 
  compose, 
  branch, 
  forMethods, 
  forPaths,
  withRetry,
  withTimeout 
} from '@struktos/core';

// Compose middlewares
const pipeline = compose(logging, auth, validation);

// Conditional branching
const authBranch = branch(
  (ctx) => ctx.request.headers['authorization'] !== undefined,
  authenticatedMiddleware,
  publicMiddleware
);

// Method-specific middleware
const postOnly = forMethods(['POST', 'PUT'], validationMiddleware);

// Path-specific middleware
const apiOnly = forPaths(['/api'], rateLimitMiddleware);

// With retry
const resilientMiddleware = withRetry(externalApiMiddleware, {
  maxRetries: 3,
  retryDelay: 1000,
});

// With timeout
const timedMiddleware = withTimeout(slowMiddleware, 5000);

Background Services

import { IntervalService, BackgroundServiceBase } from '@struktos/core';

class HealthCheckService extends IntervalService {
  readonly name = 'health-check';
  
  constructor() {
    super(30000); // Run every 30 seconds
  }
  
  protected async execute(): Promise<void> {
    console.log('Health check running...');
    // Check database, cache, external services, etc.
  }
}

app.addService(new HealthCheckService());

🏗️ Architecture

┌─────────────────────────────────────────────────────────────┐
│                      StruktosApp                            │
├─────────────────────────────────────────────────────────────┤
│  ┌─────────────────────────────────────────────────────┐   │
│  │              Middleware Pipeline                     │   │
│  │  ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐   │   │
│  │  │ Timing  │→│ Logging │→│  Auth   │→│ Router  │   │   │
│  │  └─────────┘ └─────────┘ └─────────┘ └─────────┘   │   │
│  └─────────────────────────────────────────────────────┘   │
│                          ↓                                  │
│  ┌─────────────────────────────────────────────────────┐   │
│  │            Exception Filter Chain                    │   │
│  │  ┌────────────┐ ┌────────────┐ ┌────────────┐       │   │
│  │  │ Validation │→│    HTTP    │→│  Default   │       │   │
│  │  └────────────┘ └────────────┘ └────────────┘       │   │
│  └─────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────┘
                          ↓
┌─────────────────────────────────────────────────────────────┐
│                       IAdapter                              │
│  ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐  │
│  │  Express  │ │  Fastify  │ │   gRPC    │ │   Kafka   │  │
│  └───────────┘ └───────────┘ └───────────┘ └───────────┘  │
└─────────────────────────────────────────────────────────────┘

🔌 Adapter Ecosystem

| Adapter | Package | Protocol | |---------|---------|----------| | Express | @struktos/adapter-express | HTTP | | Fastify | @struktos/adapter-fastify | HTTP | | NestJS | @struktos/adapter-nestjs | HTTP | | gRPC | @struktos/adapter-grpc (planned) | gRPC | | Kafka | @struktos/adapter-kafka (planned) | Message Queue | | RabbitMQ | @struktos/adapter-rabbitmq (planned) | Message Queue |

🔄 Context Propagation

Go-style context propagation using AsyncLocalStorage.

import { RequestContext } from '@struktos/core';

// Context is automatically propagated
async function businessLogic() {
  const ctx = RequestContext.current();
  const traceId = ctx?.get('traceId');
  const userId = ctx?.get('userId');
  
  console.log(`[${traceId}] Processing for user ${userId}`);
  
  // Available in all nested async calls
  await someNestedFunction();
}

📊 Type Safety

Full TypeScript support with generics:

interface MyContextData extends StruktosContextData {
  tenantId: string;
  permissions: string[];
}

const app = StruktosApp.create<MyContextData>();

app.use(async (ctx, next) => {
  // TypeScript knows about tenantId and permissions
  ctx.context.set('tenantId', 'tenant-123');
  ctx.context.set('permissions', ['read', 'write']);
  await next();
});

🤝 Related Packages

📄 License

MIT © Struktos.js Team

🔗 Links


Built with ❤️ for enterprise Node.js development