Skip to content

stsepelin/lukk-js

Repository files navigation

lukk-js

lukk-nuxt version lukk-core version CI Coverage License

JavaScript/TypeScript clients for lukk — minimal-dependency JWT authentication for first-party Laravel apps, plus an auth-aware fetch and reactive forms for talking to your own Laravel API correctly. Nuxt first; the core is framework-agnostic, so more bindings can follow.

Unofficial companion to lukk. Not affiliated with or endorsed by the Laravel or Nuxt teams. "Laravel" and "Nuxt" are referenced only to describe compatibility and design influence.

Pre-1.0 — expect breaking changes. lukk-core and lukk-nuxt are in the 0.x series and versioned in lockstep. Both are fully tested (100% coverage), but per semantic versioning for initial development, the public API and composable surface may change between minor versions without a major bump. Pin exact versions and read the UPGRADE guide (and each package's CHANGELOG.md) before upgrading. The 1.0 release will mark API stability.

Features

  • One composable API, every rendering mode — the same useLukkAuth() works in SSR, SPA, and SSG.
  • Two transport modes, a config switch apart — a BFF proxy that keeps tokens server-side (the browser never sees a token), or direct calls straight to lukk (the only option for fully static sites).
  • The whole lukk surfacelogin, token refresh, logout, session revocation, two-factor, step-up confirmation, and passkeys.
  • Call your own API, correctlyuseLukkFetch() is a typed, auth-aware fetch for your Laravel API: authenticated in every context (a plain $fetch silently 401s in SSR), single-flight 401 refresh, credentials never leak cross-origin, and a typed Laravel error ({ message, status, errors }) ready to bind to a form.
  • Forms, bound to Laravel validationuseLukkForm() is a reactive form in the spirit of Inertia's useForm: submit data, bind a 422 bag to per-field errors, with processing / isDirty / lifecycle hooks and automatic multipart/form-data for file uploads.
  • Silent refresh, single-flight — a 401 transparently refreshes and retries; a burst of 401s triggers exactly one refresh.
  • Typed end to end — the lukk HTTP contract mirrored in TypeScript, conformance-tested against a real lukk instance so it can't drift.
  • Tinylukk-core has zero runtime dependencies; lukk-nuxt adds only @nuxt/kit + defu.

Packages

Package What it is
lukk-core Framework-agnostic: the lukk HTTP contract types, the auth client (token attach + refresh + single-flight), and WebAuthn helpers. Use it directly in any TS app, or as the base for a binding.
lukk-nuxt A Nuxt module (Nuxt 3 and 4): auto-imported composables, useLukkFetch() + useLukkForm() for your own API, route middleware, the BFF proxy, and the transport wiring.

Transport modes

mode is a config switch — your app code never changes between them.

Mode How it works Reach for it when
bff (default) A Nitro proxy holds tokens in a sealed, server-side cookie; the browser only ever talks to your own origin. SSR or a served SPA — the most secure option, no token in the browser.
direct The client calls lukk directly. Access token in memory, refresh token in lukk's __Host- cookie. A fully static site (SSG), or a simple SPA with no runtime server.

See Transport Modes for the security trade-offs and the SSR/SPA/SSG matrix.

Requirements

  • A lukk-powered Laravel API (latest 0.x recommended — the newest client features track the latest lukk; e.g. registration needs lukk >= 0.4)
  • Node >= 20
  • Nuxt 3 or 4 (for lukk-nuxt)

Quick start

npm i lukk-nuxt
// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['lukk-nuxt'],
  lukk: {
    baseURL: 'https://api.example.com/auth', // your lukk auth routes
    mode: 'bff',                             // 'bff' (default) or 'direct'
    user: { endpoint: '/api/me' },           // your app's authenticated user route
  },
})
<script setup lang="ts">
const { user, loggedIn, login, logout } = useLukkAuth()

async function onSubmit() {
  await login({ email: email.value, password: password.value })
}
</script>

In bff mode, also set a session secret (≥ 32 chars): NUXT_LUKK_SESSION_PASSWORD=…. See Installation for the full walkthrough.

Documentation

📚 Full documentation: stsepelin.github.io/lukk-docs

lukk-js (this client) and lukk (the Laravel package) are documented together on one site — each feature page covers both the server and the client. Start with the Introduction or jump to Installation.

Planned and deliberately-deferred work is tracked in ROADMAP.md.

For AI assistants: the docs are exposed as /llms.txt + /llms-full.txt (llms.txt convention), and AGENTS.md has integration + contribution rules.

Development

pnpm install
pnpm build        # lukk-core, then lukk-nuxt
pnpm test         # 100% coverage gate on both packages
pnpm lint
pnpm dev          # the lukk-nuxt playground

Acknowledgements

lukk-js is the client half of lukk and mirrors its HTTP contract; it also borrows liberally from the Laravel and Nuxt ecosystems. Sincere thanks to their authors and maintainers — lukk-js is an unofficial companion, not affiliated with or endorsed by any of them (see the note at the top); these are simply the works that shaped it:

  • Inertia.jsuseLukkForm is modelled on Inertia's useForm: the data / processing / errors / isDirty surface, 422 error-bag binding, and remember semantics all follow its lead.
  • Nuxt — the module + auto-imported composable design, and the SSR/BFF story (a Nitro proxy holding tokens server-side) build directly on Nuxt's server/client model.
  • Laravel Sanctum & Fortify — the auth contract lukk-js speaks, and its customization philosophy, originate here (via lukk).
  • VueUse — the reference for ergonomic, composition-first composable API shapes.
  • unjslukk-core and the BFF proxy are built on ofetch and h3 / Nitro.

And the tooling: changesets (releases), unbuild + @nuxt/module-builder (builds), and Vitest (the 100%-coverage gate) — plus the Nuxt and Laravel communities that make all of this possible. 🙏

License

MIT.

About

TypeScript/Nuxt client for lukk — attaches the bearer, refreshes on 401, drives the 2FA & passkey ceremonies. lukk-core (framework-agnostic) + lukk-nuxt. The client half of lukk.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors