I’ve worked on many TypeScript projects over the years, and one recurring challenge has been managing metadata with decorators. In almost every project, handling metadata meant resorting to clunky workarounds—whether it was using reflect-metadata
in an ad-hoc way or building fragile DIY solutions that lacked proper type safety.
I tried a few things, but always ended up with sub-optimal solutions:
- Some libraries bundled in overly complex metadata systems that were way too heavyweight for simple needs.
- Homegrown solutions often ended up reinventing the wheel, resulting in code that was hard to maintain and prone to type issues.
- Other third-party tools offered impressive features but came with steep learning curves and excessive configuration, which complicated otherwise straightforward tasks.
Along came rgstry
At first, I thought, “Oh great, another metadata registry...” But it turned out to be exactly what I so often needed and never had. rgstry is lightweight, type-safe, and configurable—solving many of the pain points I’d experienced.
For example, here’s how you can create a strongly-typed metadata registry, deconstruct and alias the decorators, and use them in your code:
import { Rgstry } from 'rgstry';
// Create a registry for string metadata with a custom ID.
const LabelRegistry = Rgstry.create<string>({ id: 'label-registry' });
// Deconstruct the class metadata decorator and a helper to retrieve metadata.
const { classMetadata: Label, getClassMetadata } = LabelRegistry;
// Apply the Label decorator to tag classes.
@Label('test-1')
class Test1 {}
@Label('test-2')
class Test2 {}
// Retrieve metadata directly from class types.
console.log('Test1 metadata:', getClassMetadata(Test1)); // Expected: ['test-1']
console.log('Test2 metadata:', getClassMetadata(Test2)); // Expected: ['test-2']
rgstry is designed to be developer-friendly. It avoids the pitfalls of overly generic types, maintains strong type safety, and offers a simple API without unnecessary configuration overhead.
While rgstry’s core implementation remains completely dependency-free and explicit, it also offers optional integration with reflect-metadata for enhanced runtime type inference. This means that if you’re already using reflect-metadata in your project, rgstry can automatically pick up on method parameter types, return types, and constructor parameter types, reducing boilerplate and making advanced features—like dependency injection or dynamic routing—even smoother. It’s a flexible approach: stick with the core for simplicity, or enable reflect-metadata for a richer, more automated experience.
A small confession
I’m also the author of rgstry. While I’m happy with what it does today, there’s plenty of room for growth. I have some ideas for upcoming feature additions, but I’m eager to see contributions from the community to help shape its future.
So, if you’re a TypeScript enthusiast looking for a better way to manage metadata, give rgstry a try and let me know how it goes - Your feedback and contributions would be greatly appreciated!
You can find the source code here for closer inspection or further usage examples.
Please also feel free to ask any questions in the comments below.
Happy coding!
Top comments (1)
Vraiment c’est impressionnant je suis débutante mais j’aimerais faire votre connaissance si possible