Complete Starter Kit for Juris Framework
Full-stack reactive JavaScript framework with SSR, API routes, and static generation
# Clone the Juris Kit
git clone https://github.com/jurisjs/juris-kit.git my-app
cd my-app
npm install
# Start development server
npm run dev
# Or start production server
npm start
Visit http://localhost:3000
and you're ready to build!
Juris Kit provides everything you need to build modern web applications with the Juris framework:
juris-kit/
βββ config/
β βββ juris.config.js # Server & build configuration
βββ public/
β βββ css/styles.css # Stylesheets
β βββ js/juris-app.js # Client-side bundle
βββ source/
β βββ components/ # Reusable UI components
β βββ headless/ # Logic components (API, routing, etc.)
β βββ pages/ # Page components
β βββ app.js # Main application entry
βββ services/
β βββ db.query.js # Database/API services
βββ server.js # Production server
- π Full Async/Await Support - Native promise handling throughout the stack
- π Universal API Client - Seamless server-client API integration
- π§ Smart Hydration - Efficient client-side takeover from SSR
- π High Performance - 1,300+ req/s with 9.6ms response times
- π‘ Server-Side Rendering (SSR) - Fast initial page loads with hydration
- π RESTful API Routes - Built-in endpoints with automatic routing
- β‘ Static Site Generation - Pre-render pages for maximum performance
- π₯ Hot Reloading - Instant development feedback
- π¦ Compression - Gzip compression for production
- π CORS Support - Ready for cross-origin requests
- Router - Client-side navigation
- API Client - Universal fetch client (server + browser)
- String Renderer - HTML generation for SSR
- Swap Attributes - Dynamic content updates
The kit comes with a complete example showing all async, API, performance, and hydration features:
// source/components/AsyncUserProfile.js
const AsyncUserProfile = async (props, context) => {
const { getState, setState } = context;
try {
// Async data loading with loading states
setState('user.loading', true);
const userData = await fetch(`/api/users/${props.userId}`);
const user = await userData.json();
setState('user.data', user);
setState('user.error', null);
return {
div: { className: 'user-profile',
children: [
{ img: { src: user.avatar, alt: user.name }},
{ h2: { text: user.name }},
{ p: { text: `${user.posts} posts β’ ${user.followers} followers` }}
]
} //div.user-profile
}; //return
} catch (error) {
setState('user.error', error.message);
setState('user.loading', false);
return {
div: { className: 'error',
text: 'Failed to load user profile'
}
};
} finally {
setState('user.loading', false);
}
};
// source/headless/APIClient.js
const APIClient = (props, context) => {
const { getState, setState } = context;
return {
api: {
// Works on both server and client automatically
async fetchWithCache(endpoint, options = {}) {
const cacheKey = `api.cache.${endpoint}`;
// Check cache first
if (!options.skipCache) {
const cached = getState(cacheKey);
if (cached && Date.now() - cached.timestamp < 300000) <
8000
span class="pl-kos">{
return cached.data;
}
}
// Set loading state
setState(`api.${endpoint}.loading`, true);
try {
// Universal fetch - works on server and client
const response = await fetch(`/api${endpoint}`, {
headers: { 'Content-Type': 'application/json' },
...options
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const data = await response.json();
// Cache the result
setState(cacheKey, { data, timestamp: Date.now() });
setState(`api.${endpoint}.data`, data);
setState(`api.${endpoint}.error`, null);
return data;
} catch (error) {
setState(`api.${endpoint}.error`, error.message);
throw error;
} finally {
setState(`api.${endpoint}.loading`, false);
}
},
// High-performance batch operations
async batchRequest(endpoints) {
const promises = endpoints.map(endpoint =>
this.fetchWithCache(endpoint, { skipCache: true })
);
return await Promise.all(promises);
}
}
};
};
// source/pages/HomePage.js - Hydration-aware component
const HomePage = (props, context) => {
const { getState, setState } = context;
// Check if we're hydrating from server-side render
const isHydrating = getState('isHydration', false);
return {
div: { className: 'home-page',
children: [
{ h1: { text: 'Welcome to Juris Kit!' }},
// Conditional rendering based on hydration state
isHydrating ?
// Server-side: render immediately with data
{ div: { text: () => `Server time: ${getState('serverTime')}` }} :
// Client-side: async load fresh data
{ AsyncTimeDisplay: {} },
// Performance-optimized component loading
{ LazyCounter: {
// Only loads when visible (intersection observer)
loadWhen: 'visible',
fallback: { div: { text: 'Loading counter...' }}
}},
// API-integrated navigation
{ nav: {
children: () => {
const pages = getState('api.pages.data', []);
return pages.map(page => ({
a: {
href: page.url,
text: page.title,
// Smart prefetching on hover
onMouseEnter: () => this.prefetchPage(page.url)
}
}));
}
}} //nav
]
} //div.home-page
}; //return
};
// config/juris.config.js
module.exports = {
server: {
port: process.env.PORT || 3000,
host: '0.0.0.0',
// High-performance server options
fastify: {
keepAliveTimeout: 30000,
connectionTimeout: 60000,
maxParamLength: 100
}
},
app: {
title: 'My High-Performance Juris App',
initialState: {
// Hydration-ready state
isHydration: true,
serverTime: Date.now(),
api: { cache: {} }
}
},
// Advanced API configuration
api: {
prefix: '/api',
cors: { enabled: true, credentials: true },
rateLimit: { enabled: true, max: 100, timeWindow: '1 minute' },
// High-performance endpoints with caching
endpoints: {
'/users': {
method: 'GET',
cache: true,
handler: async (request, reply) => {
// Async database query with connection pooling
const users = await db.users.findAll({
include: ['posts', 'profile'],
cache: 300 // 5 minutes
});
return users;
}
},
'/users/:id': {
method: 'GET',
cache: true,
handler: async (request, reply) => {
const { id } = request.params;
const user = await db.users.findById(id, {
include: ['posts', 'comments'],
cache: 180 // 3 minutes
});
if (!user) {
reply.code(404);
return { error: 'User not found' };
}
return user;
}
},
// Async batch endpoint
'/batch': {
method: 'POST',
handler: async (request, reply) => {
const { requests } = request.body;
const results = await Promise.allSettled(
requests.map(req => processAPIRequest(req))
);
return { results };
}
}
}
},
// Smart static generation with async detection
htmlCache: {
generation: {
enabled: true,
outputDir: 'dist',
routes: ['/', '/about', '/users'],
ttl: 300000, // 5 minutes
onDemand: {
enabled: true,
maxFileAge: 300000,
serveStaleWhileRevalidate: true
},
// Only generate truly static routes (no async dependencies)
detectReactivity: true
}
},
// Performance optimizations
performance: {
compression: { enabled: true, threshold: 1024 },
cache: {
ssrCacheDuration: 3600, // 1 hour
staticAssetCaching: true
}
},
// Advanced hydration settings
hydration: {
strategy: 'progressive', // progressive | immediate | lazy
skipStaticContent: true,
chunkSize: 50, // Number of components to hydrate per chunk
priority: ['interactive', 'visible', 'deferred']
}
};
npm run dev
# Starts server with hot reloading at http://localhost:3000
# Create new component
touch source/components/MyComponent.js
# Register in app.js
app.registerComponent('MyComponent', MyComponent);
// In config/juris.config.js
api: {
endpoints: {
'/my-endpoint': {
method: 'POST',
handler: async (request, reply) => {
// Your API logic here
return { success: true };
}
}
}
}
npm run build
npm start
npm run generate
# Creates static files in dist/ folder
Juris Kit delivers exceptional performance with advanced async handling:
Artillery Load Test (50,000 requests):
βββ π Requests per second: 1,332 req/s
βββ β‘ Average response time: 9.6ms
βββ π 95th percentile: 15ms
βββ π― 99th percentile: 19.1ms
βββ β
Success rate: 100% (zero failures)
βββ πΎ Memory usage: Stable under load
- β‘ Non-blocking Rendering - UI stays responsive during async operations
- π Smart Promise Batching - Automatic promise collection and resolution
- π¦ Intelligent Caching - API responses cached with TTL
- π Lazy Loading - Components load only when needed
- π§ Hydration Optimization - Minimal client-side JavaScript execution
- π‘ Prefetching - Smart resource preloading on user interaction
// Built-in performance features in the kit:
// 1. Request batching
const batchedData = await api.batchRequest(['/users', '/posts', '/comments']);
// 2. Automatic caching with TTL
const userData = await api.fetchWithCache('/users/123'); // Cached for 5 minutes
// 3. Background updates
api.backgroundRefresh('/dashboard'); // Updates cache without blocking UI
// 4. Smart retries with exponential backoff
const result = await api.fetchWithRetry('/api/data', { maxRetries: 3 });
- ποΈ Fast Hydration - Only hydrates interactive components
- π Selective Hydration - Skip static content during hydration
- β‘ Progressive Enhancement - Works without JavaScript, enhanced with it
- π§ Smart State Transfer - Efficient server-to-client state synchronization
# Development
npm run dev # Start dev server with hot reload
npm run watch # Watch for file changes
# Production
npm run build # Build for production
npm start # Start production server
npm run generate # Generate static site
# Testing
npm test # Run test suite
npm run test:load # Run load tests
# Utilities
npm run clean # Clean build artifacts
npm run lint # Lint code
- π Website: https://jurisjs.com/
- π¦ NPM: https://www.npmjs.com/package/juris
- π§° GitHub Kit: https://github.com/jurisjs/juris-kit
- π» GitHub Core: https://github.com/jurisjs/juris
- π¨ Codepen: https://codepen.io/jurisauthor
- π§ͺ Online Testing: https://jurisjs.com/tests/juris_pure_test_interface.html
- Pre-configured development environment
- Example components and patterns
- Working API integration
- Hot reloading setup
- SSR configuration
- Compression and caching
- Error handling
- Performance optimizations
- Modular component structure
- Headless component patterns
- Clean separation of concerns
- Easy to extend and customize
Want to improve Juris Kit? We welcome contributions!
# Fork and clone
git clone https://github.com/yourusername/juris-kit.git
cd juris-kit
npm install
# Make your
632A
changes
# Submit a pull request
MIT License - see LICENSE file for details.
- Explore the Examples - Check out the included components and pages
- Read the Docs - Visit jurisjs.com for detailed documentation
- Join the Community - Connect with other Juris developers
- Build Something Amazing - Create your next project with Juris Kit!
Get started in seconds, build for production in minutes.
Juris Kit - The fastest way to build reactive web applications.