npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@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

npm version Node Support TypeScript License


⚠️ 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.

See: DynamoDB Table Migration Guide


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 init

This 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/purenow

Prerequisites:

  • 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 init

You'll be prompted to set up AWS CDK infrastructure. Choose Yes to have everything configured automatically.

2. Start Development

npx purenow dev

Your 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 dev

Your application is now live on CloudFront!

Next Steps:


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 8080

Building:

# Build all targets (frontend, Lambda, CDK)
npx purenow build

# Build specific target
npx purenow build --target react

Deployment:

# Deploy to development
npx purenow deploy --stage dev

# Deploy to production
npx purenow deploy --stage prod

Resource 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 dev

SEO 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-env

Diagnostics:

# Run environment checks
npx purenow doctor

# Display system information
npx purenow info

Complete 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 init

This creates:

  • .seo/ directory with SEO metadata files
  • .seo/default.seo.json with 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 dev

4. 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:

  1. Route-specific values (highest priority)
  2. Default values from default.seo.json
  3. 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 prod

Complete 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 PurenowHeadManager above Outlet
  • 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 PurenowHeadManager is 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: true in your CDK stack

Learn More: SEO Metadata Management Guide


Documentation

Getting Started

CLI

CDK & Deployment

Development

Integration

Architecture

Reference

Additional Resources

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:

  1. Reads serviceName from your CDK app (cdk/bin/app.ts)
  2. Constructs stack name using pattern {serviceName}-{stage}
  3. Queries CloudFormation for stack outputs
  4. 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-dev

Benefits

  • Zero Configuration: No .env files 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-dev

Troubleshooting

List available stacks and their outputs:

npx purenow stacks list --outputs

Use environment variables (legacy fallback):

export DYNAMO_DB_SEO_ENGINE_TABLE=my-table
npx purenow seo sync --stage dev --use-env

Learn 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:

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes with tests
  4. 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.


Support

Maintainer: Raman Marozau - [email protected]

Get Help:

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!