Skip to content

Introduction

LTIkit is a runtime-, storage-, and framework-agnostic LTI 1.3 (LTI Advantage) toolkit for JavaScript/TypeScript. It verifies LTI launches and talks to LTI services (grades, deep linking, roster) with a stateless core — only jose + fetch — and pluggable adapters for everything stateful.

The de-facto library, ltijs, assumes a long-running Express server, MongoDB, and in-process session state. That doesn’t fit modern deployment targets:

  • Serverless / edge — Vercel functions, AWS Lambda, Cloudflare Workers, Next.js route handlers: no persistent process, no in-memory cache, cold starts.
  • Bring-your-own database — teams already run Postgres/Supabase/Redis and don’t want a second datastore.
  • Framework freedom — Next.js, Hono, Remix, SvelteKit, plain Workers.

LTIkit is the opposite by construction: a stateless core with all state pushed behind small adapter interfaces, plus thin per-framework bindings. It runs anywhere JS runs, including the edge.

  • Not an auth/session system. LTIkit verifies the launch and hands you verified claims; creating your app’s user and session is your job (see Auth integration).
  • Not tied to any database, ORM, cache, or web framework.
  • Not an LTI 1.1 / Basic Outcomes library. LTI 1.3 / Advantage only.
PackagePurpose
@ltikit/coreThe stateless core: JWT verify/sign, OIDC login, launch, AGS, NRPS, deep linking, identity.
@ltikit/nextNext.js App Router bindings (Web-standard Request/Response) + iframe helpers.
@ltikit/honoHono route bindings.
@ltikit/adapter-supabasePlatformStore + NonceStore on Supabase/Postgres.
@ltikit/adapter-redisNonceStore on Redis / Upstash (serverless-friendly single-use).
@ltikit/adapter-memoryIn-memory adapters for dev/tests.

It is extracted from a production integration verified against Canvas and MoodleCloud (hosted and self-hosted) for SSO, deep linking, and grade passback.