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

@rustable/trait

v0.4.12

Published

A TypeScript library that implements Rust-like traits with compile-time type checking and runtime verification.

Readme

@rustable/trait

A TypeScript library that implements Rust-like traits with compile-time type checking and runtime verification.

✨ Features

  • 🔒 Type Safety - Type-safe trait definitions and implementations
  • 🎯 Generics - Support for generic traits and implementations
  • 🔄 Methods - Instance and static method implementations
  • 🔗 Composition - Trait-to-trait implementations
  • 💾 Memory - Memory-efficient using WeakMap for GC

📦 Installation

npm install @rustable/trait
# or
yarn add @rustable/trait
# or
pnpm add @rustable/trait

📖 Usage

Defining a Trait

import { Trait, macroTrait } from '@rustable/trait';

// Define a trait
class DisplayTrait extends Trait {
  display(): string {
    return 'default';
  }
}

// Create a trait decorator
const Display = macroTrait(DisplayTrait);

Implementing a Trait

There are several ways to implement a trait:

  1. Using the @derive decorator with default implementation:
@derive([Display])
class Point {
  constructor(
    public x: number,
    public y: number,
  ) {}
}

// The display method will use the default implementation from DisplayTrait
  1. Using implFor method with custom implementation:
class Point {
  constructor(
    public x: number,
    public y: number,
  ) {}
}

DisplayTrait.implFor(Point, {
  display() {
    return `(${this.x}, ${this.y})`;
  },
});

Using Traits

Once a trait is implemented, you can use it in several ways:

const point = new Point(1, 2);

// Method 1: Using wrap
const display = DisplayTrait.wrap(point);
console.log(display.display()); // "(1, 2)"

// Method 2: Checking implementation
if (DisplayTrait.isImplFor(point)) {
  const display = DisplayTrait.wrap(point);
  console.log(display.display());
}

Static Trait Methods

Traits can also include static methods:

class FromStrTrait extends Trait {
  static fromStr(s: string): any {
    throw new Error('Not implemented');
  }
}

const FromStr = macroTrait(FromStrTrait);

class Point {
  constructor(
    public x: number,
    public y: number,
  ) {}
}

// Implement static methods using implFor
FromStr.implFor(Point, {
  static: {
    fromStr(s: string): Point {
      const [x, y] = s.split(',').map(Number);
      return new Point(x, y);
    },
  },
});

// Use static trait methods
const point = FromStrTrait.staticWrap(Point).fromStr('1,2');

📚 API Reference

Core Functions

macroTrait

Creates a trait decorator for implementing traits at compile time.

const Display = macroTrait(DisplayTrait);
const FromStr = macroTrait(FromStrTrait);

@derive([Display, FromStr])
class Point {
  constructor(
    public x: number,
    public y: number,
  ) {}
}

// Implement custom behavior using implFor
DisplayTrait.implFor(Point, {
  display() {
    return `(${this.x}, ${this.y})`;
  },
});

FromStrTrait.implFor(Point, {
  static: {
    fromStr(s: string): Point {
      const [x, y] = s.split(',').map(Number);
      return new Point(x, y);
    },
  },
});

Trait Class Methods

The Trait class provides several static methods for trait operations:

isImplFor

Checks if a value implements the trait.

if (DisplayTrait.isImplFor(point)) {
  // point implements DisplayTrait
  const display = DisplayTrait.wrap(point);
  console.log(display.display());
}

validFor

Validates that a value implements the trait. Throws if validation fails.

// Throws if point doesn't implement DisplayTrait
DisplayTrait.validFor(point);

wrap

Wraps a value as a trait instance. Supports both instance and constructor wrapping.

// Wrap instance
const point = new Point(1, 2);
const display = DisplayTrait.wrap(point);
console.log(display.display());

// Wrap constructor
const PointDisplay = DisplayTrait.wrap(Point);
const newPoint = new PointDisplay(3, 4);

staticWrap

Wraps a class to access static trait methods.

// Wrap Point's static methods
const PointFromStr = FromStrTrait.staticWrap(Point);
const point = PointFromStr.fromStr('1,2');

implFor

Implements a trait for a target class.

DisplayTrait.implFor(Point, {
  display() {
    return `(${this.x}, ${this.y})`;
  },
});

tryImplFor

Similar to implFor, but doesn't throw if the trait is already implemented.

DisplayTrait.tryImplFor(Point, {
  display() {
    return `(${this.x}, ${this.y})`;
  },
});

📄 License

MIT © illuxiza