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

@sitblueprint/website-construct

v0.1.8

Published

A reusable AWS CDK construct for deploying static websites with optional custom domain support.

Readme

Website CDK Construct

A reusable AWS CDK construct to deploy a website via S3 and CloudFont.

Features

  • CDN caching via CloudFont
  • Deployment via S3
  • Dual domain support (e.g., deploy to both www.example.com and example.com simultaneously)
  • Hardened S3 bucket defaults with bucket-owner-only ACLs and automatic SSE
  • Direct access to the underlying S3 bucket and CloudFront distribution for advanced customization

Bucket security hardening

The construct keeps the S3 bucket accessible for static website hosting while enforcing safer defaults:

  • Bucket ACLs are blocked and ownership is enforced so only the account owner controls access.
  • Objects are encrypted at rest with S3 managed keys.
  • CloudFront OAI access is granted explicitly via a bucket policy instead of broad public access.

Installation

npm i @sitblueprint/website-construct

Usage

export class MyWebsiteStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const website = new Website(this, "MyWebsite", {
      bucketName: "my-static-site-bucket",
      indexFile: "index.html",
      errorFile: "error.html",
      notFoundResponsePagePath: "/404.html",
      domainConfig: {
        domainName: "example.com",
        subdomainName: "www",
        certificateArn: "arn:aws:acm:us-east-1:123456789012:certificate/abc123",
        includeRootDomain: true, // Optional: also deploy to example.com
      },
    });

    website.bucket; // Underlying S3 bucket
    website.distribution; // CloudFront distribution serving the site
  }
}

Pull Request Preview Environments

Use previewConfig on Website to create a pool of preview buckets (default: 2). CI can claim a slot using LRU, deploy artifacts to the assigned bucket, and release the slot when the pull request closes.

export class WebsiteWithPreviewStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const website = new Website(this, "MyWebsite", {
      bucketName: "my-static-site-bucket",
      indexFile: "index.html",
      errorFile: "error.html",
      previewConfig: {
        bucketPrefix: "my-frontend-preview",
        bucketCount: 2, // default
        maxLeaseHours: 24,
      },
    });

    new cdk.CfnOutput(this, "PreviewClaimEndpoint", {
      value: website.previewEnvironment!.claimEndpoint,
    });
    new cdk.CfnOutput(this, "PreviewReleaseEndpoint", {
      value: website.previewEnvironment!.releaseEndpoint,
    });
  }
}

API contract for CI

  • POST /claim with body {"repo":"owner/repo","prNumber":123,"commitSha":"abc"}
  • POST /heartbeat with body {"repo":"owner/repo","prNumber":123,"commitSha":"abc"}
  • POST /release with body {"repo":"owner/repo","prNumber":123}

claim and heartbeat return:

{
  "slotId": 0,
  "bucketName": "my-frontend-preview-0",
  "previewUrl": "https://....cloudfront.net"
}

GitHub Actions shape

name: preview
on:
  pull_request:
    types: [opened, reopened, synchronize, closed]

jobs:
  preview:
    runs-on: ubuntu-latest
    concurrency: preview-${{ github.event.pull_request.number }}
    steps:
      - uses: actions/checkout@v4
      - if: github.event.action != 'closed'
        run: npm ci && npm run build
      - name: Claim or release slot
        env:
          REPO: ${{ github.repository }}
          PR: ${{ github.event.pull_request.number }}
          SHA: ${{ github.sha }}
          CLAIM_URL: ${{ secrets.PREVIEW_CLAIM_ENDPOINT }}
          RELEASE_URL: ${{ secrets.PREVIEW_RELEASE_ENDPOINT }}
        run: |
          if [ "${{ github.event.action }}" = "closed" ]; then
            curl -sS -X POST "$RELEASE_URL" -H "content-type: application/json" -d "{\"repo\":\"$REPO\",\"prNumber\":$PR}"
            exit 0
          fi

          RESPONSE=$(curl -sS -X POST "$CLAIM_URL" -H "content-type: application/json" -d "{\"repo\":\"$REPO\",\"prNumber\":$PR,\"commitSha\":\"$SHA\"}")
          echo "$RESPONSE" > preview-slot.json
          BUCKET=$(jq -r '.bucketName' preview-slot.json)
          URL=$(jq -r '.previewUrl' preview-slot.json)
          aws s3 sync ./dist "s3://$BUCKET" --delete
          echo "Preview URL: $URL"

Development

  • Build: npm run build
  • Test: npm run test

License

MIT