@worktif/purenow
v0.2.188
Published
Serverless app running on AWS Lambda with support for server-side rendering, caching, and CI/CD.
Readme
@worktif/purenow
⚠️ IMPORTANT: DynamoDB Migration Required
If you're upgrading from a previous version with SEO enabled, you'll need to migrate your DynamoDB table. The table naming has changed to support seamless CloudFormation updates.
Overview
Purenow is a serverless web framework for AWS Lambda that enables server-side rendering with CloudFront CDN distribution, API Gateway routing, and S3 caching. Build production-ready web applications that deploy to AWS with a single command.
Key Features
- Automatic Infrastructure - CDK constructs provision all AWS resources
- Isomorphic Routing - Unified routing for server and client
- CloudFront CDN - Global edge caching for optimal performance
- Server-Side Rendering (SSR) - Full SSR support on AWS Lambda with streaming
- DynamoDB SEO - Optional SEO metadata persistence
- S3 Caching - Intelligent page caching with ETag validation
- Custom HTML Templates - Full control over HTML shell via
public/index.html - Bundle Optimization - Minimal Lambda cold starts with smart externalization
- TypeScript First - Full type safety across the stack
- CLI Tools - Simple commands for development and deployment
What You Get
CloudFront → API Gateway → Lambda (SSR) → S3 (Cache)
↓
DynamoDB (SEO)Purenow handles the entire AWS infrastructure setup, letting you focus on building your application.
Installation
New Projects (Recommended)
Initialize a new project with all configuration included:
npx @worktif/purenow initThis creates a complete project structure with:
- Application setup with React frontend
- AWS CDK infrastructure
- Development server configuration
- All dependencies installed automatically
Existing Projects
Add Purenow to your existing project:
npm install @worktif/purenowPrerequisites:
- Node.js >= 18
- AWS Account with CLI configured
- AWS CDK CLI installed globally:
npm install -g aws-cdk
Note: Frontend dependencies are installed automatically during purenow init.
Quick Start
Get your application running in 3 minutes:
1. Initialize Project
mkdir my-app && cd my-app
npx @worktif/purenow initYou'll be prompted to set up AWS CDK infrastructure. Choose Yes to have everything configured automatically.
2. Start Development
npx purenow devYour app runs at http://localhost:3000 with hot module replacement.
3. Deploy to AWS
# Configure AWS credentials (if not already done)
aws configure
# Deploy to development environment
npx purenow deploy --stage devYour application is now live on CloudFront!
Next Steps:
- Read the Getting Started Guide for detailed tutorials
- Customize your HTML Template with
public/index.html - Explore Integration Examples
- Learn about CDK Customization
Usage
CLI Commands
Purenow provides a comprehensive CLI for managing your application:
Development:
# Start local dev server
npx purenow dev
# Custom port
npx purenow dev --port 8080Building:
# Build all targets (frontend, Lambda, CDK)
npx purenow build
# Build specific target
npx purenow build --target reactDeployment:
# Deploy to development
npx purenow deploy --stage dev
# Deploy to production
npx purenow deploy --stage prodResource Management:
# List CloudFormation stacks
npx purenow stacks list
# List stacks with outputs
npx purenow stacks list --outputs
# Filter by stage
npx purenow stacks list --stage devSEO Management:
# Sync SEO metadata to DynamoDB (auto-discovers table)
npx purenow seo sync --stage dev
# Use explicit stack name
npx purenow seo sync --stage dev --stack-name my-custom-stack
# Use environment variables (legacy)
npx purenow seo sync --stage dev --use-envDiagnostics:
# Run environment checks
npx purenow doctor
# Display system information
npx purenow infoComplete CLI Reference: docs/cli/commands.md
Programmatic Usage
Initialize Purenow in your application:
import { purenow, purenowRouter, ErrorBoundary } from '@worktif/purenow';
import { routes } from './routes';
import App from './App';
// Initialize Purenow with SSR support
purenow({
app: ({ router }) => <App router={router} />,
router: purenowRouter({
router: routes,
defaults: {
HydrateFallback: () => <div>Loading...</div>,
ErrorBoundary,
},
}),
config: {
serviceName: process.env.REACT_APP_STACK_NAME || 'my-app',
stage: (process.env.REACT_APP_STAGE as 'dev' | 'staging' | 'prod') || 'dev',
},
});Note: Purenow currently uses React for the frontend. See Integration Guide for details.
HTML Template Customization
Customize your application's HTML shell by creating a public/index.html file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!-- Your custom meta tags -->
<meta name="description" content="My awesome application" />
<!-- Reference static assets with {{STATIC_URL}} -->
<link rel="icon" href="{{STATIC_URL}}/favicon.ico" />
<link rel="stylesheet" href="{{STATIC_URL}}/styles/main.css" />
<title>My Application</title>
</head>
<body>
<div id="root-purenow"></div>
</body>
</html>Key Features:
- Full HTML Control: Define your own
<head>structure and meta tags - {{STATIC_URL}} Placeholder: Automatically replaced with CloudFront CDN URL
- SEO Merging: Database metadata intelligently merges with your template
- Static Assets: All files in
public/uploaded to S3 automatically
Learn More: HTML Template Customization Guide
CDK Construct Library
Import and customize the Purenow stack in your CDK application:
import * as cdk from 'aws-cdk-lib';
import { PurenowStack } from '@worktif/purenow/infra';
const app = new cdk.App();
new PurenowStack(app, 'MyApp-Dev', {
stage: 'dev',
serviceName: 'my-app',
enableSeo: true,
env: {
account: process.env.CDK_DEFAULT_ACCOUNT,
region: 'us-east-1',
},
});
app.synth();CDK Documentation: docs/cdk/usage.md
SEO Integration
Purenow provides built-in SEO metadata management with DynamoDB persistence and automatic head tag updates during client-side navigation.
Quick Setup
1. Initialize SEO Configuration
npx purenow seo initThis creates:
.seo/directory with SEO metadata files.seo/default.seo.jsonwith framework-wide defaults- Route-specific files for each route in your application
2. Configure Default SEO
Edit .seo/default.seo.json to set framework-wide defaults:
{
"route": "[seo-defaults]",
"title": "My Application",
"description": "Application description",
"keywords": ["keyword1", "keyword2"],
"ogTitle": "My Application",
"ogDescription": "Social media description",
"ogImage": "/og-image.png",
"twitterCard": "summary_large_image",
"robots": "index, follow"
}3. Sync to DynamoDB
npx purenow seo update --stage dev4. Add PurenowHeadManager to Your Router
Create a Layout component with PurenowHeadManager:
import { PurenowHeadManager } from '@worktif/purenow';
import { Outlet } from 'react-router';
const Layout: React.FC = () => {
return (
<>
<PurenowHeadManager />
<Outlet />
</>
);
};Use Layout in your router configuration and App component:
import { purenow, purenowRouter } from '@worktif/purenow';
import App from './App';
// Define routes with Layout
const routes = [
{
path: '/',
element: <Layout />, // Layout with PurenowHeadManager
children: [
{ index: true, element: <HomePage /> },
{ path: 'about', element: <AboutPage /> },
{ path: 'products/:id', element: <ProductPage /> }
]
}
];
// Initialize Purenow - router is provided automatically
purenow({
app: ({ router }) => <App router={router} />, // router comes from Purenow Core
router: purenowRouter({
router: routes,
defaults: {}
}),
config: {
serviceName: 'my-app',
stage: 'dev'
}
});Key Point: The router parameter in app: ({ router }) is provided by the Purenow Core. You don't need to create createBrowserRouter manually - Purenow handles this internally.
Where to Get the Router
The router is provided by Purenow Core in the app function parameter:
purenow({
app: ({ router }) => <App router={router} />, // ← router comes from here
router: purenowRouter({ ... }),
config: { ... }
});Important: Don't create your own router with createBrowserRouter(). Use the router parameter provided by the Purenow Core.
Key Components
PurenowHeadManager
- Automatically updates
<title>and meta tags during client-side navigation - Must be placed inside your router (typically in a Layout component above
<Outlet />) - Subscribes to route changes and updates document head
- Handles Open Graph, Twitter Cards, and JSON-LD structured data
usePurenowSeoMeta() Hook
- Access SEO metadata in your components
- Returns current route's SEO data
import { usePurenowSeoMeta } from '@worktif/purenow';
function MyComponent() {
const seo = usePurenowSeoMeta();
return <h1>{seo?.title}</h1>;
}Route-Specific SEO
Override defaults for specific routes by creating route files:
// .seo/about.seo.json
{
"route": "/about",
"title": "About Us - My Application",
"description": "Learn more about our company"
}Merge Priority:
- Route-specific values (highest priority)
- Default values from
default.seo.json - Hardcoded fallbacks (lowest priority)
Multi-Environment Support
Deploy different SEO configurations per environment:
# Development
npx purenow seo update --stage dev
# Staging
npx purenow seo update --stage staging
# Production
npx purenow seo update --stage prodComplete Example
Full integration with Purenow framework:
import { purenow, purenowRouter, PurenowHeadManager } from '@worktif/purenow';
import { Outlet } from 'react-router';
import App from './App';
// Layout component with PurenowHeadManager
const Layout = () => (
<>
<PurenowHeadManager /> {/* Manages SEO */}
<Header />
<Outlet /> {/* Renders current page */}
<Footer />
</>
);
// Define routes
const routes = [
{
path: '/',
element: <Layout />, // Layout above Outlet
children: [
{ index: true, element: <HomePage /> },
{ path: 'about', element: <AboutPage /> }
]
}
];
// Initialize Purenow
purenow({
app: ({ router }) => <App router={router} />, // Use router from Purenow Core
router: purenowRouter({
router: routes,
defaults: {}
}),
config: {
serviceName: 'my-app',
stage: 'dev'
}
});Key Points:
- Layout component contains
PurenowHeadManageraboveOutlet - Router is provided by Purenow Core via
app: ({ router }) - SEO updates automatically on every route change
- Works for both SSR and client-side navigation
Verification
Check in Browser:
DevTools → Elements → <head>You should see:
<title>Your Title</title>
<meta name="description" content="Your description">
<meta property="og:title" content="Your OG title">
<!-- etc. -->Check SSR (View Page Source): SEO tags should be present in the initial HTML from the server.
Troubleshooting
SEO not updating on navigation:
- Ensure
PurenowHeadManageris inside your router (in Layout component) - Check browser console for errors
Wrong title showing:
- Check
.seo/files for the current route - Verify DynamoDB has correct data:
npx purenow seo update --stage dev - Check merge priority (route-specific > defaults > hardcoded)
SEO not in SSR:
- Ensure Lambda has access to DynamoDB
- Check CloudWatch logs for SEO loading errors
- Verify
enableSeo: truein your CDK stack
Learn More: SEO Metadata Management Guide
Documentation
Getting Started
- Installation Guide - Detailed installation instructions
- Quick Start - Step-by-step tutorial
- First Deployment - Deploy your first app
CLI
- Commands Reference - Complete CLI command documentation
- Configuration - CLI configuration options
- Workflows - Common development workflows
CDK & Deployment
- CDK Usage Guide - Using the CDK construct library
- CDK Migration - Migrating existing applications
- Deployment Overview - Deployment process
- Bootstrap Guide - AWS CDK bootstrap
- Troubleshooting - Common deployment issues
Development
- Local Setup - Development environment setup
- Build System - Understanding the build process
- Bundle Optimization - Optimizing bundle size
- Testing Guide - Testing strategies
Integration
- Integration Overview - Integrating Purenow with React
- React Setup - React application structure
- Router Integration - React Router setup
- HTML Template Customization - Customize HTML shell with
public/index.html - Examples - Complete working examples
Architecture
- Architecture Overview - System architecture
- Request Flow - SSR request flow
- Lambda Layer - Lambda layer architecture
- Code Organization - Project structure
Reference
- API Reference - Complete API documentation
- Configuration Reference - All configuration options
- Environment Variables - Environment variable reference
Additional Resources
- Migration Guide - Version migration guide
- Testing Documentation - Manual testing guides
- Advanced Topics - Advanced usage patterns
Full Documentation Index: docs/README.md
CloudFormation Resource Resolution
Purenow CLI commands automatically discover AWS resource names from CloudFormation stack outputs, eliminating the need for manual .env configuration.
How It Works
When you run CLI commands like purenow seo sync --stage dev, the system:
- Reads
serviceNamefrom your CDK app (cdk/bin/app.ts) - Constructs stack name using pattern
{serviceName}-{stage} - Queries CloudFormation for stack outputs
- Extracts resource identifiers (DynamoDB tables, S3 buckets, etc.)
No manual configuration required!
Setup
Export serviceName from your CDK app:
// cdk/bin/app.ts
export const serviceName = 'purenow-qa1';
const app = new cdk.App();
new PurenowStack(app, 'PurenowStack', {
serviceName,
// ...
});Example
# Your CDK app exports:
# export const serviceName = 'purenow-qa1';
# Stack deployed as: purenow-qa1-dev
# CLI automatically uses it:
npx purenow seo sync --stage dev
# ✅ Resolved stack: purenow-qa1-dev
# ✅ Using DynamoDB table: purenow-qa1-seo-devBenefits
- Zero Configuration: No
.envfiles to maintain - Works with any stack name: Automatically discovers custom service names
- No Configuration Drift: Always uses the actual deployed resources
- Multi-Environment: Automatically resolves correct resources per stage
- Error Prevention: Eliminates typos and outdated resource names
Override Stack Name
If needed, specify stack name explicitly:
npx purenow seo sync --stage dev --stack-name my-custom-stack-devTroubleshooting
List available stacks and their outputs:
npx purenow stacks list --outputsUse environment variables (legacy fallback):
export DYNAMO_DB_SEO_ENGINE_TABLE=my-table
npx purenow seo sync --stage dev --use-envLearn More: Stack Auto-Discovery Guide
Package Exports
Purenow provides multiple entry points for different use cases:
| Export | Path | Description |
|--------|------|-------------|
| Main Library | @worktif/purenow | React components, hooks, and utilities |
| CDK Construct | @worktif/purenow/infra | PurenowStack CDK construct |
| Lambda Bundle | @worktif/purenow/lambda | Pre-built Lambda handler bundle |
| CLI Tool | @worktif/purenow/cli.js | Command-line interface |
Example:
// Import Purenow library
import { purenow, PurenowRouter } from '@worktif/purenow';
// Import CDK construct
import { PurenowStack } from '@worktif/purenow/infra';Examples
Basic Web Application
import { purenow, purenowRouter } from '@worktif/purenow';
import { RouteObject } from 'react-router';
import { HomePage } from './pages/HomePage';
import { AboutPage } from './pages/AboutPage';
import App from './App';
const routes: RouteObject[] = [
{
path: '/',
element: <HomePage />,
},
{
path: '/about',
element: <AboutPage />,
},
];
purenow({
app: ({ router }) => <App router={router} />,
router: purenowRouter({
router: routes,
}),
config: {
serviceName: 'my-app',
stage: 'dev',
},
});Custom CDK Stack
import { PurenowStack } from '@worktif/purenow/infra';
import * as cdk from 'aws-cdk-lib';
const app = new cdk.App();
new PurenowStack(app, 'MyApp-Prod', {
stage: 'prod',
serviceName: 'my-app',
enableSeo: true,
lambdaMemorySize: 1024,
lambdaTimeout: 30,
});More Examples: docs/integration/examples.md
Contributing
We welcome contributions! Please follow these steps:
- Fork the repository
- Create a feature branch
- Make your changes with tests
- Submit a pull request
For detailed contribution guidelines, see CONTRIBUTING.md.
Security: Report vulnerabilities privately to [email protected]
License
This project is licensed under the Elastic License 2.0.
- See LICENSE for the full license text
- See NOTICE for attribution and relicensing details
- See CHANGELOG.md for version history
Support
Maintainer: Raman Marozau - [email protected]
Get Help:
- Documentation
- GitHub Issues
- Email Support (use "[purenow]" in subject)
For enterprise support and integration guidance, contact us via email.
Ready to get started? Run npx @worktif/purenow init to create your first serverless React application!
