Skip to main content
The Cookie helper provides utilities for reading, writing, and managing HTTP cookies in your Hono application, including support for signed cookies and cookie prefixes.

Import

import { getCookie, setCookie, deleteCookie, getSignedCookie, setSignedCookie } from 'hono/cookie'

Getting Cookies

Retrieve a specific cookie value by name:
import { getCookie } from 'hono/cookie'

app.get('/cookie', (c) => {
  const value = getCookie(c, 'yummy_cookie')
  return c.text(`Cookie value: ${value}`)
})

Get All Cookies

Retrieve all cookies as an object:
import { getCookie } from 'hono/cookie'

app.get('/cookies', (c) => {
  const cookies = getCookie(c)
  return c.json(cookies)
})

Setting Cookies

Set a simple cookie with default options:
import { setCookie } from 'hono/cookie'

app.get('/set', (c) => {
  setCookie(c, 'delicious_cookie', 'macha')
  return c.text('Cookie set!')
})
// Sets: delicious_cookie=macha; Path=/
Set a cookie with custom options:
import { setCookie } from 'hono/cookie'

app.get('/set-advanced', (c) => {
  setCookie(c, 'great_cookie', 'banana', {
    path: '/',
    secure: true,
    domain: 'example.com',
    httpOnly: true,
    maxAge: 1000,
    expires: new Date(Date.UTC(2030, 11, 24, 10, 30, 59, 900)),
    sameSite: 'Strict',
  })
  return c.text('Cookie set with options!')
})
path
string
default:"/"
The path where the cookie is available
secure
boolean
Whether the cookie should only be sent over HTTPS
domain
string
The domain where the cookie is available
httpOnly
boolean
Whether the cookie is accessible only through HTTP(S)
maxAge
number
Maximum age in seconds
expires
Date
Expiration date of the cookie
sameSite
'Strict' | 'Lax' | 'None'
SameSite attribute for CSRF protection
prefix
'secure' | 'host'
Cookie prefix for enhanced security

Signed Cookies

Signed cookies provide tamper protection by including a cryptographic signature.
import { setSignedCookie } from 'hono/cookie'

app.get('/set-signed', async (c) => {
  const secret = 'secret chocolate chips'
  await setSignedCookie(c, 'delicious_cookie', 'macha', secret)
  return c.text('Signed cookie set!')
})
import { getSignedCookie } from 'hono/cookie'

app.get('/get-signed', async (c) => {
  const secret = 'secret chocolate chips'
  const value = await getSignedCookie(c, secret, 'delicious_cookie')
  
  if (value === false) {
    return c.text('Invalid signature!')
  }
  
  return c.text(`Signed value: ${value}`)
})
getSignedCookie returns false if the signature is invalid, undefined if the cookie doesn’t exist, or the cookie value if valid.

Get All Signed Cookies

import { getSignedCookie } from 'hono/cookie'

app.get('/get-all-signed', async (c) => {
  const secret = 'secret chocolate chips'
  const cookies = await getSignedCookie(c, secret)
  return c.json(cookies)
})
Cookie prefixes provide additional security guarantees enforced by browsers.

Secure Prefix

Cookies with __Secure- prefix must be set with the secure flag:
import { setCookie, getCookie } from 'hono/cookie'

app.get('/set-secure', (c) => {
  setCookie(c, 'token', 'secret123', {
    prefix: 'secure'
  })
  return c.text('Secure cookie set!')
})
// Sets: __Secure-token=secret123; Path=/; Secure

app.get('/get-secure', (c) => {
  const token = getCookie(c, 'token', 'secure')
  return c.text(`Token: ${token}`)
})

Host Prefix

Cookies with __Host- prefix must be secure, have path /, and no domain:
import { setCookie, getCookie } from 'hono/cookie'

app.get('/set-host', (c) => {
  setCookie(c, 'session', 'abc123', {
    prefix: 'host'
  })
  return c.text('Host cookie set!')
})
// Sets: __Host-session=abc123; Path=/; Secure

app.get('/get-host', (c) => {
  const session = getCookie(c, 'session', 'host')
  return c.text(`Session: ${session}`)
})
With host prefix, the domain and custom path options are automatically ignored for security.

Deleting Cookies

Basic Delete

import { deleteCookie } from 'hono/cookie'

app.get('/delete', (c) => {
  deleteCookie(c, 'delicious_cookie')
  return c.text('Cookie deleted!')
})

Delete with Options

Match the same options used when setting the cookie:
import { deleteCookie } from 'hono/cookie'

app.get('/delete-advanced', (c) => {
  deleteCookie(c, 'delicious_cookie', {
    path: '/',
    secure: true,
    domain: 'example.com',
  })
  return c.text('Cookie deleted with options!')
})

Get Deleted Value

deleteCookie returns the value that was deleted:
import { deleteCookie } from 'hono/cookie'

app.get('/delete-and-return', (c) => {
  const deletedValue = deleteCookie(c, 'delicious_cookie')
  return c.text(`Deleted: ${deletedValue}`)
})
For advanced use cases, generate cookie strings without setting them:
import { generateCookie } from 'hono/cookie'

const cookieString = generateCookie('name', 'value', {
  path: '/',
  secure: true,
  httpOnly: true
})
// Returns: name=value; Domain=example.com; Path=/; HttpOnly; Secure
import { generateSignedCookie } from 'hono/cookie'

const cookieString = await generateSignedCookie(
  'name',
  'value',
  'secret',
  { path: '/', secure: true }
)

Multiple Cookies

Set multiple cookies in a single response:
import { setCookie } from 'hono/cookie'

app.get('/multiple', (c) => {
  setCookie(c, 'cookie1', 'value1')
  setCookie(c, 'cookie2', 'value2')
  setCookie(c, 'cookie3', 'value3')
  return c.text('Multiple cookies set!')
})

Best Practices

Use Signed Cookies

Use signed cookies for sensitive data that needs tamper protection

Set HttpOnly

Use httpOnly: true for cookies that don’t need JavaScript access

Use Secure Flag

Always use secure: true in production to ensure HTTPS-only transmission

Match Delete Options

When deleting cookies, use the same path and domain used when setting

Security Considerations

Never store sensitive data in unsigned cookies - Cookies can be easily read and modified by clients. Use signed cookies or server-side sessions for sensitive data.
Cookie prefixes (__Secure- and __Host-) provide additional security enforced by browsers. Use them for sensitive cookies.

Build docs developers (and LLMs) love