DEV Community

genix
genix

Posted on • Edited on

new web framework

Hey everyone!

I’m still working hard on Gland, and after a lot of refactoring and R&D, I’m excited to share some of the new developments. Gland is getting closer to its final syntax, and I’ve decided to make it fully event-driven (EDS-based), inspired by frameworks like NestJS and Angular.

It means:

  • DI system: Similar to NestJS, for easy dependency injection.
  • Controller, Import, Export: Just like NestJS, but with a twist—Channels replace traditional providers.
  • Channels instead of Providers: Channels handle logic, making your app more modular and scalable.
  • Pure and lightweight: Built from the ground up with minimal dependencies, no unnecessary packages—everything is kept lean and efficient.

Why EDS? (Event-Driven System)

Instead of returning data directly from controllers, everything in Gland is driven by events. This makes the app more modular, scalable, and flexible. Events trigger actions and responses, making the whole flow smoother and more intuitive.

Example:

@Controller('users')
class UserController {
  @Get('/:id')
  getUser(ctx: Context) {
    const result = ctx.emit('read:server', ctx);
    try {
      throw Error('Hello world');
    } catch (error) {
      return ctx.emit('read:server:error', { error, result });
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Here, ctx.emit('read:server', ctx) sends an event called users:read:server, and a Channel listens for it:

@Channel('users')
class UserChannel {
  @On('read:server')
  get(ctx: Context) {
    return 10;
  }
}
Enter fullscreen mode Exit fullscreen mode

Now the entire data flow is event-driven

What’s Next?

Right now, Gland is still under development, and the ideas are evolving. The core concepts are being implemented, and I'm exploring new ways to make event-driven architecture more intuitive for web development.

Contribute or Share Your Ideas!

Gland is under active development, and the idea is still evolving. If you support the project, feel free to star it, open issues, submit pull requests, or share your ideas on GitHub. Whether you spot a bug or have a new feature in mind, your feedback is incredibly valuable.

I’d love to hear your thoughts—does this event-driven approach feel more flexible and modular compared to the traditional patterns? Or do you see potential challenges? Let’s start a conversation!

Top comments (34)

Collapse
 
keyru_nasirusman profile image
keyru Nasir Usman • Edited

Do we really need another new web framework?

Collapse
 
m__mdy__m profile image
genix

It really depends on what you’re looking for. Express still "works," and NestJS still "works," so if those fit your needs, there's no reason to switch.

But whether we need a new framework or not comes down to what problems you're trying to solve. Gland isn't trying to replace NestJS it’s taking a different, fully event-driven approach that makes code more modular and flexible. If that resonates with your project’s needs, then it’s worth considering. If not, sticking with what already works is totally fine.

Collapse
 
greenanttech profile image
Yohan Moore • Edited

This is the proper response. Even if it is the millionth JavaScript framework it is worth the attempt. At best it becomes something popular at worst you learned a lot about the problems that frameworks are trying to solve.

Thread Thread
 
m__mdy__m profile image
genix

I agree. every new project is an opportunity to learn and grow, even if it's as simple as a basic calculator. For me, even if Gland doesn't become a huge success, the process of building it, the challenges I’ve faced, and the research I've conducted are incredibly valuable. Every experience, including failures, contributes to future successes as long as we learn from them.

Collapse
 
killvung profile image
killvung

This one is unique due to its event driven nature

Collapse
 
ersansaribal profile image
Ersan Saribal

Short answer? Yes. Even thousands more, as long people are creating them in the name of innovation.

Collapse
 
sgebb profile image
sgebb

Not sure I understand this. You're raising an event users.read.server assuming that some channel is implementing it, but the raiser has no type info to know what the channel will return. Am I supposed to do just project wide searches for strings to figure things out?

Collapse
 
m__mdy__m profile image
genix

Good question! Right now, Gland’s event system is highly dynamic, allowing you to emit events without strict type constraints. While this provides flexibility, as you pointed out, it can make tracking responses harder.

One of the planned improvements is to introduce better type safety for emitted events, ensuring that the caller knows exactly what to expect. This could involve a type mapping system that links events to expected return types, making event-driven logic more predictable.

I’ll definitely take a closer look at this and explore ways to improve type inference in Gland’s event-driven flow. Thanks for the feedback!

Collapse
 
nurhusien1970 profile image
Omar N Idris

In technology I see a recycling of ideas. One technology claims an improvement then comes another with its own baggages. I like the dynamics but the big question is why has not humanity succeeded in bringing a better technology we can all agree on? Is it even possible? What is wrong with us?

Collapse
 
m__mdy__m profile image
genix

The problem is not with us, but with our idea of ​​progress. Perhaps progress does not mean reaching a final and perfect technology at all, but rather the same constant movement between ideas, tests and failures.

Collapse
 
mr_nova profile image
Ijeoma M. Jahsway

I like @m_mdy_m response but here's another perspective. Maybe the problem is just that humans can't remain fixed on one thing. They say change is nature and we die the moment we stop changing and improving.

If all humanity agrees to use one perfect framework then that eliminates variety and subsequently, change. There has to be options.

Collapse
 
tareksalem profile image
tareksalem

Nice work, liked the idea, I would suggest to go beyond controllers and give more concrete implementation to leverage ore advanced patterns and architectures like domain driven design and clean architecture, I think as framework if u give some guideline and specific patterns to leverage those architectures with the use of events it will be very awesome

Also we need to think how can we build a package that uses events for db interactions and managing transactions
One last thing, we can use this pattern to add extra functionality for saving all interactions happen on the server through events, for example controller emits to service and service emits to db then emits back controller then to channel, we can add one extra functionality that records those events so it can be very useful for logs and traces

Collapse
 
m__mdy__m profile image
genix

Thanks for the great insights! I really like the idea of going beyond just controllers and providing structured guidelines for architectures like DDD and Clean Architecture. That’s definitely something worth exploring—especially how event-driven patterns can naturally fit into these architectures and enhance modularity and maintainability.

I've already been working extensively on this idea and actively exploring ways to integrate these principles into Gland. Additionally, I plan to release third-party modules for database interactions that seamlessly integrate with Gland’s event-driven approach. These modules will provide a clean, decoupled way to manage data without tightly coupling the database logic to the application’s core.

In the future, I will also publish detailed documentation and guidelines on how to build third-party extensions for Gland, ensuring that developers can easily create plugins and integrations that align with its architecture. Of course, this will come after Gland reaches a stable release.

I also love the suggestion about event-based logging and tracing. Implementing a system that tracks and records all emitted events could be incredibly useful for debugging, monitoring, and even replaying events for auditing purposes. This is definitely something I’ll be looking into as Gland evolves.

Really appreciate the feedback! If you have any concrete ideas, specific use cases, or even suggestions on how you'd like to see these features implemented, feel free to share—I’d love to refine Gland’s event-driven approach even further.

Collapse
 
kenzhemir profile image
Miras Kenzhegaliyev

Hey!

This is very interesting approach 👍 with event driven framework, I feel like writing state-machines in the backend would fit nicely.

I have a thought about the ctx.emit. I feel like it should not return result of the channel's event handler (10). Emitter usually should not know or care who handled the event and listeners should act on their own behalf.
Typically, if original emitter needs data, some listener would emit a response event, which the original emitter would be listening to.

Collapse
 
m__mdy__m profile image
genix

Thank you for your thoughtful comment! You’ve raised a really important point about how event-driven systems should work, and I completely agree with the idea that emitters shouldn’t necessarily care about who handles the event or how it’s handled. This is actually one of the core principles behind Gland’s design, and I’d love to explain how we’ve approached this.

In Gland, ctx.emit is designed to give developers flexibility. While it can return the result of the handler, it doesn’t have to. This is intentional because we want to support both scenarios:

  1. When you need a response: Sometimes, you might want to ensure that an event has been handled before moving forward. For example, if you’re processing a payment, you might want to confirm that the payment was logged before proceeding. In this case, waiting for a response from the handler makes sense.

  2. When you don’t need a response: In other cases, like sending a notification, you might not care about the result at all. Here, you can simply emit the event and let the listeners handle it independently.

This flexibility allows developers to choose the right approach for their specific use case. If you prefer a more decoupled workflow where the emitter doesn’t wait for a response, you can design your system so that listeners emit follow-up events, and the emitter listens for those if needed. This keeps the emitter completely unaware of who’s handling the event or how it’s being handled, which aligns with your suggestion.

For example, imagine a scenario where a user signs up:

  • The controller emits a user:signup event.
  • A listener handles the event, saves the user to the database, and emits a user:created event.
  • Another listener picks up the user:created event and sends a welcome email.

In this case, the emitter doesn’t need to know about the database or the email service. It just broadcasts the event, and the listeners handle the rest.

That said, I completely understand your concern about the emitter potentially becoming too involved in the handling process. This is something I’ll keep in mind for future updates. For example, we could introduce stronger type constraints or event-response contracts to make it clearer when and how responses should be used. This would help developers avoid unintended coupling while still maintaining the flexibility that Gland offers.

Thanks again for sharing your thoughts! Your feedback is incredibly valuable, and it’s exactly this kind of discussion that helps make Gland better. If you have more ideas or suggestions, I’d love to hear them!

Collapse
 
mike_murphy_f7cd964d9a5af profile image
Mike Murphy

There are many cases where you may care that the event was handled before you moved on to something else, you may not care who has handled the event, but you many care that it has been handled.

Collapse
 
m__mdy__m profile image
genix

Thank you for highlighting that nuance! I completely agree—there are indeed many cases where you might need confirmation that an event was handled before moving on, even if you don't care who handled it. In Gland, we've intentionally designed ctx.emit to be flexible. You can simply emit an event without waiting for a response when that's all you need, or you can structure your workflow so that follow-up events or asynchronous callbacks provide the confirmation you require.

For instance, in scenarios where processing order is critical (like logging a payment or updating a user record), you can have a listener emit a follow-up event to signal that the handling is complete. This allows you to wait for confirmation without coupling your emitter to a specific handler. It’s all about letting you choose the approach that best fits your use case.

Collapse
 
shishantbiswas profile image
Shishant Biswas

Time to reset the clock

Collapse
 
zafar_khan_a9c906f42f5020 profile image
Zafar Khan

Gland is a new event-driven JavaScript web framework inspired by NestJS and Angular. It features dependency injection, controllers, and modular channels instead of providers, making apps more scalable and flexible. Using an Event-Driven System (EDS), actions are triggered by events rather than direct responses, enhancing modularity. The framework is lightweight, with minimal dependencies. Gland is still evolving, and feedback or contributions are welcome to refine its approach! 🚀

Collapse
 
sanagkerkar profile image
Sanag Kerkar

Good, Keep going. I'm also making my own Framework for web still not have done that much. 😅

Collapse
 
webyguy profile image
Ted

Ive been commercially using Blazor for web development for over 3 years now, the freedom of no javascript and all the tooling is amazing, also really fast and responsive. Its 2025 no need for such an old language as Javascript any more and crazy tooling and dependancies.

Collapse
 
xdefyinggravity profile image
Defying Gravity

Great idea! I see a lot of potential for microservices here. Breaking the code into asynchronous, event-driven modules can make it non-blocking and much more efficient, which really helps with the performance across services.