MCPcopy Index your code
hub / github.com/CodeDredd/h3-compression

github.com/CodeDredd/h3-compression @v1.0.1

Chat with this repo
repository ↗ · DeepWiki ↗ · release v1.0.1 ↗ · + Follow
31 symbols 101 edges 16 files 2 documented · 6%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

H3-compression

npm version npm downloads bundle JSDocs License

Handles compression for H3

Features

✔️  Zlib Compression: You can use zlib compression (brotli, gzip and deflate)

✔️  Stream Compression: You can use native stream compressions (gzip, deflate)

✔️  Compression Detection: It uses the best compression which is accepted

✔️  h3 v1 & v2: Works with both h3 v1 and v2

Install

# Using npm
npm install h3-compression

# Using yarn
yarn add h3-compression

# Using pnpm
pnpm add h3-compression

Usage (h3 v1)

import { createServer } from 'node:http'
import { createApp, eventHandler, toNodeListener } from 'h3'
import { useCompressionStream } from 'h3-compression'

const app = createApp({ onBeforeResponse: useCompressionStream }) // or { onBeforeResponse: useCompression }
app.use(
  '/',
  eventHandler(() => 'Hello world!'),
)

createServer(toNodeListener(app)).listen(process.env.PORT || 3000)

Example using listhen for an elegant listener:

import { createApp, eventHandler, toNodeListener } from 'h3'
import { listen } from 'listhen'
import { useCompressionStream } from 'h3-compression'

const app = createApp({ onBeforeResponse: useCompressionStream }) // or { onBeforeResponse: useCompression }
app.use(
  '/',
  eventHandler(() => 'Hello world!'),
)

listen(toNodeListener(app))

Usage (h3 v2)

In h3 v2 the response is an immutable web Response and the onBeforeResponse hook was removed. Use the compression / compressionStream middleware instead — they read the response returned by the next handler and replace it with a compressed one.

import { createServer } from 'node:http'
import { H3, toNodeHandler } from 'h3'
import { compression } from 'h3-compression'

const app = new H3()

app.use(compression()) // or app.use(compressionStream())
app.get('/', () => 'Hello world!')

createServer(toNodeHandler(app)).listen(process.env.PORT || 3000)

You can also force a specific method (e.g. compression('gzip')) instead of detecting it from the Accept-Encoding header.

[!NOTE] compressionStream uses the native CompressionStream, which only supports gzip and deflate (no brotli).

Nuxt 3 & 4

If you want to use it in Nuxt you can define a nitro plugin.

server/plugins/compression.ts

import { useCompression } from 'h3-compression'

export default defineNitroPlugin((nitro) => {
  nitro.hooks.hook('render:response', async (response, { event }) => {
    // Skip internal nuxt routes (e.g. error page)
    if (['/_nuxt', '/__nuxt'].some(prefix => getRequestURL(event).pathname.startsWith(prefix)))
      return

    if (!response.headers?.['content-type']?.startsWith('text/html'))
      return

    await useCompression(event, response)
  })
})

[!NOTE]
useCompressionStream doesn't work right now in nitro. So you just can use useCompression

Cached routes (SWR / ISR) and /server/api

The render:response hook only runs for freshly rendered SSR pages. Responses served from the Nitro route cache (routeRules with swr / isr) and /server/api handlers go through the beforeResponse hook instead. Use it to compress those too:

server/plugins/compression.ts

import { useCompression } from 'h3-compression'

export default defineNitroPlugin((nitro) => {
  nitro.hooks.hook('beforeResponse', async (event, response) => {
    // Skip internal nuxt routes (e.g. error page)
    if (['/_nuxt', '/__nuxt'].some(prefix => event.path.startsWith(prefix)))
      return

    await useCompression(event, response)
  })
})

useCompression compresses string, Buffer/Uint8Array and JSON (object) bodies and skips everything else (e.g. streams), so binary assets are left untouched. If you only want to compress specific content types, guard on response.headers?.['content-type'] before calling it.

Utilities

H3-compression has a concept of composable utilities that accept event (from eventHandler((event) => {})) as their first argument and response as their second.

Zlib Compression

  • useGZipCompression(event, response)
  • useDeflateCompression(event, response)
  • useBrotliCompression(event, response)
  • useCompression(event, response)

Stream Compression

  • useGZipCompressionStream(event, response)
  • useDeflateCompressionStream(event, response)
  • useCompressionStream(event, response)

Middleware (h3 v2)

  • compression(method?)  – middleware using zlib (brotli, gzip, deflate)
  • compressionStream(method?)  – middleware using the native CompressionStream (gzip, deflate)
  • compressResponse(event, value, method?)  – low-level helper returning a compressed Response
  • compressResponseStream(event, value, method?)  – low-level stream helper returning a compressed Response

Sponsors

Releated Projects

License

MIT License © 2023-PRESENT Gregor Becker

Extension points exported contracts — how you extend this code

RenderResponse (Interface)
(no doc)
src/helper.ts

Core symbols most depended-on inside this repo

compress
called by 4
src/helper.ts
useCompression
called by 3
src/compression.ts
getAnyCompression
called by 3
src/helper.ts
compressStream
called by 3
src/helper.ts
compression
called by 3
src/middleware.ts
useGZipCompression
called by 2
src/compression.ts
h3Export
called by 2
src/helper.ts
ensureToResponse
called by 2
src/helper.ts

Shape

Function 30
Interface 1

Languages

TypeScript100%

Modules by API surface

src/helper.ts12 symbols
test/dist-bundling.test.ts4 symbols
src/compression.ts4 symbols
test/compression-v1.test.ts3 symbols
src/compressionStream.ts3 symbols
test/compression-stream.test.ts2 symbols
src/middleware.ts2 symbols
test/compression.test.ts1 symbols

For agents

$ claude mcp add h3-compression \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact