See @rhtml in Action
Experience the power of functional reactive components
import { Component, DefineDependencies } from '@rhtml/component'; import { Container, Injectable } from '@rxdi/core'; import { html, LitElement, property } from '@rxdi/lit-html'; import { BehaviorSubject } from 'rxjs'; import { map } from 'rxjs/operators'; @Injectable() class CounterService { counter = 55; } @Component({ Settings: { selector: 'app-root', }, Providers: DefineDependencies(CounterService)(Container), State: function(this: AppComponent, [counterService]) { return this.subject.pipe( map(value => ({ counter: value + counterService.counter })) ); }, Render: ([counterService]) => function(this, { counter }) { return html` <p>Count: ${counter}</p> <button @click=${() => this.increment()}> Increment </button> `; } }) export class AppComponent extends LitElement { @property({ type: Number }) private count = 0; subject = new BehaviorSubject(0) increment() { this.subject.next(this.count++); } }
Why Choose @rhtml?
Modern web development made simple, powerful, and maintainable
Lightning Fast
Built on Web Components and LitElement for optimal performance. Minimal overhead with maximum efficiency.
Reactive by Design
Native RxJS integration for reactive programming. Build responsive UIs with declarative data flows.
Type Safe
Full TypeScript support with excellent IDE integration. Catch errors at compile time, not runtime.
Component Based
Build reusable, composable components with Web Components standards. Share components across projects easily.
Dependency Injection
Powerful DI container inspired by Angular. Manage services and dependencies with ease.
Full Stack
Frontend and backend in one framework. Fastify integration with GraphQL, MongoDB, and AMQP support.
More Examples
Real examples showing the power and simplicity of @rhtml
🔄 Reactive State Management
import { Component, DefineDependencies } from '@rhtml/component'; import { Container, Injectable } from '@rxdi/core'; import { html, LitElement, property } from '@rxdi/lit-html'; import { interval } from 'rxjs'; import { map } from 'rxjs/operators'; @Injectable() class CounterService { counter = 55; } @Component({ Settings: { selector: 'counter', }, Providers: DefineDependencies(CounterService)(Container), State: function(this: CounterComponent, [counterService]) { return interval(1000).pipe( map((value) => ({ counter: this.counter + counterService.counter + value, })) ); }, Render: ([counterService]) => function(this, { counter }) { return html` <div> <h2>Counter: ${counter}</h2> <p>Service Counter: ${counterService.counter}</p> </div> `; } }) export class CounterComponent extends LitElement { @property({ type: Number }) counter: number = 0; }
🎯 Backend API with Fastify
import { Controller, Route, Subscribe } from '@rhtml/fastify'; import { Subscribe } from '@rhtml/amqp'; import { MessageService } from './message.service'; @Controller() export class NotificationController { constructor(private messageService: MessageService) {} @Route({ url: '/publish-message', }) async sendNotification(notification: any) { await this.messageService.publish('my-message-queue', {}); } @Subscribe({ queue: 'my-message-queue', consumeOptions: { noAck: false, }, }) async myMessageQueueSubscription( message: ConsumeMessage, channel: AmqpChannel ) { channel.ack(); } }
📊 GraphQL Integration
import { Component, DefineDependencies } from '@rhtml/component'; import { Container, Injectable } from '@rxdi/core'; import { html, LitElement, property } from '@rxdi/lit-html'; import { of } from 'rxjs'; @Injectable() class UserService { getUser(userId: string) { return { id: userId, name: 'John Doe', email: 'john@example.com' }; } } @Component({ Settings: { selector: 'user-list', }, Providers: DefineDependencies(UserService)(Container), State: function(this: UserComponent, [userService]) { return of({ user: userService.getUser(this.userId), time: new Date().getSeconds(), }); }, Render: ([userService]) => function(this, { user, time }) { return html` <div> <h2>${user.name}</h2> <p>Email: ${user.email}</p> <p>Current time: ${time}</p> </div> `; } }) export class UserComponent extends LitElement { @property({ type: String }) userId = ''; }
💾 MongoDB with Mongoose
import { Injectable, Inject } from '@rhtml/di'; import { AmqpChannel, AmqpService, ConsumeMessage } from '@rhtml/amqp'; @Injectable() export class MessageService { constructor(private amqpService: AmqpService) {} async publish(name: string, payload: any) { await this.amqpService.publish(name, { payload: {}, }); } } @Injectable() export class UserService { constructor( @Inject(Repositories) private repos: Repositories, private messageService: MessageService ) {} createFile(file: File) { return this.repos.file.create(file); } listFiles() { return this.repos.file.find(); }
Component System Comparison
Choose the right approach for your project
@rxdi/lit-html
First Generationimport { Component, html, LitElement, property } from '@rxdi/lit-html'; @Component({ selector: 'simple-counter', template: () => html` <div> <h2>Count: ${this.count}</h2> <button @click=${this.increment}> +1 </button> </div> ` }) export class SimpleCounter extends LitElement { @property({ type: Number }) count = 0; increment() { this.count++; } }
@rhtml/component
Second Generationimport { Component, DefineDependencies } from '@rhtml/component'; import { Container, Injectable } from '@rxdi/core'; import { html, LitElement, property } from '@rxdi/lit-html'; import { interval } from 'rxjs'; import { map } from 'rxjs/operators'; @Injectable() class CounterService { counter = 55; } @Component({ Settings: { selector: 'reactive-counter', }, Providers: DefineDependencies(CounterService)(Container), State: function(this, [counterService]) { return interval(1000).pipe( map((value) => ({ counter: this.counter + counterService.counter + value, })) ); }, Render: ([counterService]) => function(this, { counter }) { return html` <div> <h2>Counter: ${counter}</h2> <p>Service Counter: ${counterService.counter}</p> </div> `; } }) export class ReactiveCounter extends LitElement { @property({ type: Number }) counter: number = 0; }
Ready to Build Something Amazing?
Join the community of developers building modern web applications with @rhtml