---
title: "@playstack/extension"
description: "MV3-safe authentication, typed messaging, validated storage, permissions, and refresh coordination for browser extensions."
tags: ["package","identity","extension","mv3","wxt","browser","pro"]
---

{/* package-access:start */}

> **Pro.** Covered by the Playstack Pro License. Registry access is required; check preview availability before installing. See [package access](/docs/packages#access-policy).

{/* package-access:end */}

`@playstack/extension` supplies runtime primitives for a Playstack-connected
Manifest V3 extension. WXT owns scaffolding, entrypoints, manifests, bundling,
and store builds; Playstack owns boundaries that must survive a disposable
service worker.

{/* package-install:start */}

## Install

After confirming [preview access](/docs/packages#access-policy), install the package at your application's shared Playstack version:

```sh
npm install --save-exact @playstack/extension@0.1.0-beta.1
```

Check the peer requirements below before choosing a runtime or provider.

{/* package-install:end */}

## Compose authentication

```ts
import { createClientAuth } from '@playstack/client-auth'
import {
  createExtensionAuthorizationLauncher,
  createExtensionTokenStorage,
  createWebLockRefreshCoordinator,
} from '@playstack/extension'

const auth = createClientAuth({
  clientId: 'browser-extension',
  authorizationEndpoint,
  redirectUri: browser.identity.getRedirectURL(),
  scopes: ['profile'],
  transport,
  launcher: createExtensionAuthorizationLauncher(browser.identity),
  storage: createExtensionTokenStorage({
    session: browser.storage.session,
    local: browser.storage.local,
  }),
  refreshCoordinator: createWebLockRefreshCoordinator(navigator.locks),
})
```

Short-lived access credentials live in session storage. Refresh credentials
live in local storage, while a Web Lock serializes rotation across popup,
content-script, and service-worker contexts. The extension opens the
application’s existing browser authorization flow and never receives a user’s
password.

## Messaging, storage, and permissions

`defineMessages()` validates request and response payloads around typed runtime
handlers. `defineExtensionStorage()` and `createExtensionStorage()` validate
values every time they cross browser storage. `ensureExtensionPermissions()`
checks existing optional permissions before prompting and fails explicitly when
the user declines.

All APIs are structural: pass the browser facade supplied by WXT or another
extension runtime without importing that framework into Playstack.

## Boundary

Module memory and timers are never durable MV3 state. Register browser event
handlers at module evaluation, reconstruct state on wake, and use alarms for
long delays. `@playstack/lint` supplies explicit extension presets for remote
code, long worker timers, and mutable worker-memory state.

{/* package-reference:start */}

## API entry points and requirements

Reference snapshot: `@playstack/extension@0.1.0-beta.1`. Import only the entry point your runtime needs. Paths below are relative to the installed package; use **Go to Definition** in your editor to inspect exact parameters, return types and overloads. Do not import the declaration-file paths directly.

| Public entry point | Declaration file |
| --- | --- |
| `@playstack/extension` | `./dist/index.d.ts` |
| `@playstack/extension/auth` | `./dist/auth.d.ts` |
| `@playstack/extension/messaging` | `./dist/messaging.d.ts` |
| `@playstack/extension/permissions` | `./dist/permissions.d.ts` |
| `@playstack/extension/storage` | `./dist/storage.d.ts` |
| `@playstack/extension/playstack.integration.json` | No TypeScript declaration (asset or metadata export). |
| `@playstack/extension/package.json` | No TypeScript declaration (asset or metadata export). |

Node.js engine requirement: `>=20`. This is not a claim that every entry point works in browsers or Workers.

### Peer dependencies

This package declares no peer dependencies. Its ordinary dependencies are resolved by the package manager.

For a complete first program, start with [Getting started](/docs/getting-started). For API lookup and partial-example conventions, see [Reading the reference](/docs/packages#reading-the-reference). Provider failures, lifecycle requirements and application responsibilities remain described in the guide above; types alone do not establish production safety.

{/* package-reference:end */}
