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

@virke/nextjs-adapter

v1.1.0

Published

Fastly deployment target for Next.js via [vinext](https://github.com/unjs/vinext) (Cloudflare's Next.js on Vite reimplementation).

Readme

@virke/nextjs-adapter

Fastly deployment target for Next.js via vinext (Cloudflare's Next.js on Vite reimplementation).

Features

  • Fastly Compute deployment target for vinext (Vite Environment API plugin)
  • FastlyKVCacheHandler for ISR using Fastly KV Store (4-10ms warm reads)
  • Static/SSR split: static assets to Object Storage (free VCL), SSR on Compute
  • Zero cold starts on Fastly's global edge network
  • Service chaining to virke-api for DB/auth
  • Traffic-aware pre-rendering using Fastly log data (future)

Architecture

Build & Deploy Flow

Next.js App
    ↓
  vinext (Vite compilation)
    ↓
  Fastly Deployment Target
    ↓
    ├─→ Static Assets → Object Storage → VCL serving (free)
    └─→ SSR/RSC Routes → Fastly Compute Wasm → Edge execution

Runtime Architecture

Request
    ↓
Fastly Edge
    ├─→ Static assets? → Object Storage (VCL, <1ms)
    └─→ Dynamic route? → Compute@Edge
            ├─→ ISR cached? → KV Store (4-10ms)
            ├─→ SSR render → vinext runtime
            └─→ DB/Auth needed? → Service chain to virke-api

Installation

bun add @virke/nextjs-adapter vinext

Usage

1. Configure Vite

Create or update vite.config.ts:

import { defineConfig } from 'vite'
import { vinext } from 'vinext'
import { fastlyDeploymentTarget } from '@virke/nextjs-adapter/deployment-target'

export default defineConfig({
  plugins: [
    vinext(),
    fastlyDeploymentTarget({
      serviceId: process.env.FASTLY_SERVICE_ID,
      apiToken: process.env.FASTLY_API_TOKEN,
      kvStore: 'next_cache',
      staticBucket: 'virke-sites',
      staticPrefix: '/my-app/v1'
    })
  ]
})

2. Configure ISR Cache Handler

Create app/cache-config.ts:

import { setCacheHandler } from 'next/cache'
import { FastlyKVCacheHandler } from '@virke/nextjs-adapter/cache-handler'

// Initialize ISR cache handler for Fastly KV Store
setCacheHandler(new FastlyKVCacheHandler({
  kvStore: 'next_cache',
  keyPrefix: 'isr_',
  defaultTtl: 31536000 // 1 year
}))

Import this file in your root layout or _app.tsx:

import './cache-config'

3. Configure Fastly Resources

Add to fastly.toml:

name = "my-nextjs-app"
description = "Next.js app on Fastly via vinext"
authors = ["[email protected]"]
language = "javascript"

[local_server]
  [local_server.kv_stores]
    [local_server.kv_stores.next_cache]

[setup.kv_stores.next_cache]
  [setup.kv_stores.next_cache.link]
    resource_id = "your-kv-store-id"

4. Environment Variables

Create .env:

FASTLY_SERVICE_ID=your-service-id
FASTLY_API_TOKEN=your-api-token
VIRKE_STATIC_PREFIX=/my-app/v1

5. Build & Deploy

bun run build

The deployment target will:

  1. Build your Next.js app with vinext
  2. Split static assets from SSR code
  3. Upload static assets to Object Storage
  4. Compile SSR code to Fastly Compute Wasm
  5. Deploy to your Fastly service

API Reference

fastlyDeploymentTarget(config)

Vite plugin for deploying vinext output to Fastly.

Config:

interface FastlyDeploymentConfig {
  serviceId: string          // Fastly Compute service ID
  apiToken?: string          // Fastly API token (optional for build-only)
  kvStore?: string           // KV Store for ISR cache
  staticBucket?: string      // Object Storage bucket for static assets
  staticBackend?: string     // Backend name (default: "object_storage")
  staticPrefix?: string      // Path prefix (e.g., "/my-app/v1")
  apiBackend?: string        // virke-api backend (default: "virke_api")
}

FastlyKVCacheHandler

ISR cache handler using Fastly KV Store.

Methods:

class FastlyKVCacheHandler {
  constructor(config: CacheHandlerConfig)

  async get(key: string): Promise<CacheEntry | null>
  async set(key: string, value: CacheEntry, ttl?: number): Promise<void>
  async delete(key: string): Promise<void>
  async revalidateTag(tag: string): Promise<void>
  async tag(key: string, tags: string[]): Promise<void>
  async stats(): Promise<{ entries: number; prefixes: string[] }>
}

createFastlyServer(config)

Create a Fastly Compute server for Next.js SSR/RSC routes.

Config:

interface FastlyServerConfig {
  kvStore: string                                      // KV Store for ISR
  staticBackend?: string                               // Object Storage backend
  staticPrefix?: string                                // Static asset prefix
  apiBackend?: string                                  // virke-api backend
  vinextHandler: (request: Request) => Promise<Response>  // vinext SSR handler
}

Returns:

interface FastlyServer {
  handle(request: Request): Promise<Response>
}

Performance

ISR Cache (KV Store)

| Operation | Latency | Notes | |-----------|---------|-------| | Warm read | 4-10ms | Cache hit | | Cold read | ~50ms | Includes deserialization | | Write | ~450ms | Small entries (<10KB) | | Revalidate | ~100ms | Surrogate key purge + KV delete |

Static Assets (Object Storage + VCL)

| Operation | Latency | Notes | |-----------|---------|-------| | CDN hit | <1ms | VCL serving from POP cache | | CDN miss | 10-30ms | Fetch from Object Storage |

SSR Rendering (Compute@Edge)

| Operation | Latency | Notes | |-----------|---------|-------| | Simple page | 10-30ms | Static props, no DB | | DB query | 20-50ms | Service chain to virke-api | | Complex page | 50-100ms | Multiple DB queries |

Fastly Resources

Required Services

  • Compute service: Runs SSR/RSC code (StarlingMonkey Wasm runtime)
  • VCL service (optional): Serves static assets from Object Storage

Required Resources

  • KV Store: ISR cache (next_cache)
  • Object Storage bucket: Static assets (virke-sites)
  • Backend (Compute→Object Storage): object_storage
  • Backend (Compute→virke-api): virke_api (for DB/auth)

Resource Configuration

KV Store:

fastly kv-store create --name=next_cache
fastly resource-link create --version=latest --resource-id=<store-id>

Object Storage:

# Use Fastly control panel or AWS CLI
aws s3 mb s3://virke-sites --endpoint-url=https://eu-central.object.fastlystorage.app

Service Chaining:

[setup.backends.virke_api]
  address = "virke-api.edgecompute.app"
  port = 443
  override_host = "virke-api.edgecompute.app"

Examples

Basic Next.js App

// app/page.tsx
export const revalidate = 60 // ISR: revalidate every 60 seconds

export default async function Home() {
  const data = await fetch('https://api.example.com/data')
  const json = await data.json()

  return <div>Hello {json.name}</div>
}

With Virke DB

// app/users/page.tsx
import { virkeEnv } from '@virke/runtime'

const env = virkeEnv({ db: 'my-db' })

export default async function Users() {
  const users = await env.db.query('SELECT * FROM users')

  return (
    <ul>
      {users.rows.map(user => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  )
}

Tag-based Revalidation

// app/posts/[id]/page.tsx
import { unstable_cache } from 'next/cache'

export default async function Post({ params }: { params: { id: string } }) {
  const post = await unstable_cache(
    () => fetchPost(params.id),
    ['post', params.id],
    { tags: [`post-${params.id}`] }
  )()

  return <article>{post.content}</article>
}

// app/actions.ts
'use server'

import { revalidateTag } from 'next/cache'

export async function updatePost(id: string) {
  // ... update post in DB
  await revalidateTag(`post-${id}`)
}

Limitations & Roadmap

Current Limitations

  • vinext is experimental: API may change frequently
  • No local dev yet: Requires Fastly Compute for testing
  • Build artifacts: Manual Wasm compilation (will be automated)
  • Traffic-aware pre-rendering: Not yet implemented

Roadmap

  • [ ] Implement actual Wasm compilation in deployment target
  • [ ] Add S3 upload logic for static assets
  • [ ] Integrate with @virke/fastly-client for service deployments
  • [ ] Traffic-aware pre-rendering from Fastly logs
  • [ ] Local dev server with Fastly CLI
  • [ ] Edge middleware support
  • [ ] Image optimization with Fastly Image Optimizer

Comparison to Vercel

| Feature | Vercel | Virke + vinext | |---------|--------|----------------| | SSR latency | 50-200ms | 10-100ms | | ISR cache | Edge Network | KV Store (4-10ms) | | Static serving | Edge Network | Object Storage + VCL (<1ms) | | Cold starts | 50-500ms | 0ms (Wasm) | | Global POPs | ~100 | ~70 (Fastly) | | Cost | $20/mo Pro | $0-50/mo (usage-based) |

Related Packages

License

Apache-2.0

Contributing

See CONTRIBUTING.md for guidelines.