tramvai
Modular framework for universal React applications
Quick start
Powerful and functional CLI to create, develop and build applications
$ npm init @tramvai@latest new-app
$ cd new-app && npm start
Universal
- Application rendering on the server and hydration on the client
- Full control over data fetching
- Safe execution of server and client code
Modular
- Wide possibilities of built-in modules
- Easy extends by new functionality
import { Module } from '@tramvai/core';
@Module({
providers: [{
provide: 'logger',
useValue: console
}]
})
class LoggerModule {}
Fast
- Minimum framework size
- Best practices for loading client code
- Modules for collecting metrics on the server and client
Dependency Injection
- Flexibility and reduced code cohesion
- Lazy initialization of dependencies
import { Module } from '@tramvai/core';
@Module({
providers: [{
provide: 'logger',
useValue: console
}]
})
class LoggerModule {}
@Module({
providers: [{
provide: 'service',
useFactory: (deps) => {
return new Service({ logger: deps.logger });
},
deps: {
logger: 'logger'
}
}]
})
class ServiceModule {}
React
- Support for modern library features (Concurrent Mode)
- First-class developer experience with Fast Refresh
- Flexible mechanism for building a page layout
Effective state management
- Redux-like library
- Decentralized mechanism for subscriptions to changes
- Lack of boilerplate code
- Redux DevTools support
import {
createReducer,
createEvent,
useSelector,
useActions
} from '@tramvai/state';
const incrementAction = createEvent('increment');
const countReducer = createReducer('count', 0)
.on(incrementAction, (state) => state + 1);
const Component = () => {
const count = useSelector('count', (state) => state);
const increment = useActions(incrementAction);
return (
<div>
<div>{count}</div>
<button onClick={increment}>+</button>
</div>
);
}
Chain of commands
- The ability to add an action to each stage of the application
- Parallel execution of actions at each stage for maximum efficiency
@Module({
providers: [
{
provide: commandLineListTokens.resolvePageDeps,
useFactory: ({ logger }) => () => {
logger.info('Fetch page data');
},
deps: {
logger: 'logger'
}
multi: true
}
]
})
export class CommandLineLoggingModule {}