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 🙏

© 2026 – Pkg Stats / Ryan Hefner

sterad

v1.0.2

Published

Host your SPAs with SSR experience, no extra work, gain SEO and Fast Content delivery benefits..

Readme

Sterad - "Host your SPAs with SSR experience, no extra work, gain SEO and Fast Content delivery."

Sterad is an innovative server solution that brings SEO-friendly server-side rendering capabilities to single-page applications without requiring complex SSR infrastructure. By implementing a unique client-server caching mechanism, Sterad captures rendered SPA content and serves it as static HTML to search engines and subsequent visitors.

🌟 Features

  • SEO Optimization: Serve fully-rendered HTML to crawlers
  • Progressive Caching: Builds cache organically as users visit pages
  • Hybrid Caching: Memory + disk cache with LRU eviction
  • Zero Framework Lock-in: Works with React, Vue, Angular, and other SPAs
  • Minimal Configuration: Simple TOML-based setup
  • Lightweight: <5KB client script with no dependencies
  • Security Focused: HTML sanitization and bot detection

🚀 Why Sterad?

Traditional SPAs face critical SEO challenges due to their client-rendered nature. While solutions exist, they come with tradeoffs:

| Solution | Pros | Cons | | -------------------------- | ----------------------------- | ------------------------------------- | | Static Site Generation | Fast, SEO-friendly | Requires rebuilds for content changes | | Server-Side Rendering | Dynamic, SEO-friendly | Complex setup, high server load | | Client-Side Rendering | Simple, dynamic | Poor SEO, slow initial load | | Sterad | Dynamic, SEO-friendly, simple | Requires user traffic to build cache |

Sterad bridges the gap by providing near-SSR quality for search engines while maintaining the development simplicity of pure client-side SPAs.

⚙️ How It Works

Architecture Overview

sequenceDiagram
    participant Client as User/Bot Browser
    participant Sterad as Sterad Server
    participant Cache as Sterad Cache (Memory & Disk)
    participant SPA as SPA Dist Files

    Client->>Sterad: 1. Requests Resource (GET /path)

    Sterad->>Cache: 2. Check Memory Cache
    alt Cache Hit
        Cache-->>Sterad: 3a. Return Cached Content
        Sterad-->>Client: 4a. Serve Cached Content
    else Cache Miss
        Sterad->>Sterad: 3b. Is it a Static Asset?
        alt Yes, Static Asset
            Sterad->>SPA: 4b. Read Static File
            alt File Exists
                SPA-->>Sterad: 5b. Static Content
                Sterad->>Cache: 6b. Add to Memory Cache
                Sterad-->>Client: 7b. Serve Static Content
            else File Not Found
                Sterad-->>Client: 5c. 404 Not Found
            end
        else No, Not Static Asset
            Sterad->>Sterad: 4c. Should Path Be Cached?
            alt Yes, Cacheable
                Sterad->>Cache: 5c. Check Disk Cache
                alt Disk Cache Hit
                    Cache-->>Sterad: 6c. Return Cached HTML
                    Sterad->>Cache: 7c. Add to Memory Cache
                    Sterad-->>Client: 8c. Serve Cached HTML
                else Disk Cache Miss
                    Sterad-->>Client: 6d. Serve SPA Shell + Inject Script
                    Client->>Sterad: 7d. POST Rendered HTML to /__sterad_capture
                    Sterad->>Sterad: 8d. Sanitize HTML
                    Sterad->>Cache: 9d. Write to Disk Cache
                    Sterad-->>Client: 10d. Confirmation
                end
            else No, Not Cacheable
                Sterad-->>Client: 5d. Serve SPA Shell (No Inject)
            end
        end
    end

    Client->>Sterad: Hard Reload (DELETE /__sterad_capture)
    Sterad->>Cache: Clear Cache for Path
    Sterad-->>Client: Confirmation

Core Components

  1. Client-Side Script:

    • Injected into uncached SPA responses
    • Captures rendered DOM after 1 second
    • Sanitizes content by removing scripts and event handlers
    • Sends sanitized HTML to server via POST
  2. Sterad Server:

    • Bun.js-based HTTP server
    • Hybrid caching system (memory + disk)
    • Route-based caching rules
    • HTML sanitization pipeline
    • SPA shell injection
  3. Configuration:

    • TOML-based config file
    • Route pattern matching
    • Cache management settings

📦 Installation

Prerequisites

  • Bun v1.0.0 or newer
  • Built SPA (production build)

Setup Process

  1. Install Sterad globally:

    bun add sterad
  2. Create configuration file (sterad.toml):

    # Required configuration
    spa_dist = "./dist"
    port = 9081
    cache_routes = ["/*"]
    memory_cache_limit = 100
    
    # Optional configuration
    not_cache_routes = ["/admin/*", "/api/*"]
  3. Add build script to your package.json:

    "scripts": {
      "build": "vite build",
      "start": "sterad"
    }
  4. Start the server:

    bun run start

🔧 Configuration

Sterad uses a TOML configuration file with the following options:

| Key | Required | Default | Description | | ---------------------- | -------- | ---------------------- | -------------------------------------------- | | spa_dist | Yes | - | Path to SPA build directory | | port | Yes | - | Server port | | cache_routes | Yes | - | Route patterns to cache (supports wildcards) | | memory_cache_limit | Yes | - | Maximum in-memory cache entries | | not_cache_routes | No | [] | Routes to exclude from caching | | cache_dir | No | spa_dist/.sterad_cache | Custom cache directory | | sanitization_level | No | "strict" | HTML sanitization level |

Route Pattern Examples

# Cache all routes
cache_routes = ["/*"]

# Cache only product pages
cache_routes = ["/products/*", "/categories/*"]

# Exclude admin routes
not_cache_routes = ["/admin/*", "/dashboard"]

🛡️ Security Model

Sterad implements multiple security layers to prevent XSS and malicious content injection:

  1. Client-Side Sanitization:
    • Removes all <script> tags
    • Removes event handlers (onclick, onload, etc.)
    • Disables javascript: URIs
  2. Server-Side Sanitization:
    • Removes all <script> and <style> tags
    • Removes event handlers (onclick, onload, etc.)
    • Disables javascript: URIs

Upcoming Security Fixes

  1. Implement DOMPurify for HTML sanitization
  2. Add path normalization with traversal protection
  3. Implement HMAC content signing
  4. Add security headers to all responses
  5. Implement server-side bot detection
  6. Add rate limiting to POST/DELETE endpoints

Without these fixes, Sterad should not be deployed in any public-facing environment due to high risk of XSS compromises and cache poisoning attacks.

📊 Performance

Sterad is optimized for high performance with:

  • Hybrid Caching:

    • Hot-requests served from memory
    • Warm storage on disk
    • LRU eviction policy
    • Non-Blocking I/O:

🌐 Deployment

Docker Deployment

FROM oven/bun:1.0

WORKDIR /app
COPY . .
RUN bun install

CMD ["bun", "run", "start"]

Build and run:

docker build -t sterad-app .
docker run -p 9081:9081 sterad-app

🚨 Current Limitations

  1. Initial Cache Population:

    • Requires real user traffic to build cache
    • First crawler visit might receive unstyled content
  2. Dynamic Content:

    • Time-sensitive content may become stale
  3. Framework Constraints:

    • Requires specific root element selectors
    • Invalidates automatically when cached page is reloaded
  4. Security Model:

    • Not suitable for user-generated content
    • Limited tests for protection against advanced XSS vectors

🛠 Troubleshooting

Common Issues

Cache not updating:

  1. Check hard reload handling

Content not captured:

  1. Verify root element matches these selectors:
    const selectors = [
      '[data-wrapper="app"]',
      "#root",
      "#app",
      "#__next",
      '[role="main"]',
    ];
  2. Check for CSP conflicts

Performance options:

  1. Adjust memory cache size:
    memory_cache_limit = 200
  2. Exclude static assets:
    not_cache_routes = ["/static/*"]

🚧 Contributing

We welcome contributions! Please follow these steps:

  1. Fork the repository
  2. Create a feature branch:
    git checkout -b feat/awesome-feature
  3. Commit your changes:
    git commit -m "feat: implement awesome feature"
  4. Push to your branch:
    git push origin feat/awesome-feature
  5. Open a pull request

Development Setup

# Clone repository
git clone https://github.com/your/sterad.git

# Install dependencies
bun install

# Run in development mode
bun run dev

# Run tests
bun run test

For support, contact [email protected].

📞 Support

For information, visit Codedynasty or email [email protected].


Codedynasty © 2022-present, Codedynasty Contributors.