lti-tool Documentation
    Preparing search index...

    lti-tool Documentation

    LTI Tool

    npm Build status

    LTI Tool

    Modern LTI 1.3 toolkit, built for TypeScript.

    The first serverless-native LTI 1.3 library for Node.js. Built for modern cloud architectures with pluggable storage and framework adapters.

    Key features

    • Serverless-first - Optimized for AWS Lambda, Cloudflare Workers
    • Pluggable storage - DynamoDB, Memory, PostgreSQL (planned), MySQL (planned)
    • Modern frameworks - Hono (primary), Express/Fastify (planned)
    • Security-focused - JWT verification, nonce validation, replay attack prevention
    • Performance - 6.5ms average execution time, scales to zero
    • Cost-effective - Under $0.001 per 1000 LTI launches

    Fully Implemented LTI 1.3 Specification:

    • ✅ OIDC Authentication Flow
    • ✅ Assignment and Grade Services (AGS) - Score submission, line items, results
    • ✅ Names and Role Provisioning Services (NRPS) - Member roster access
    • ✅ Deep Linking - Content selection and placement
    • ✅ Dynamic Registration - Automated tool registration
    • ✅ Security - JWT verification, nonce validation, replay attack prevention
    • Examples Repository - Comprehensive example implementations
    • Documentation Site - Auto-generated from JSDoc
    • Storage Adapters - PostgreSQL, MySQL
    • Framework Support - Express, Fastify, Astro, React, Angular

    Create a new Hono app

    npm create hono@latest
    

    Install the packages

    npm install @lti-tool/core @lti-tool/hono @lti-tool/memory
    

    Create a minimal Hono powered LTI tool

    import { Hono } from 'hono';
    import { LTITool } from '@lti-tool/core';
    import {
    jwksRouteHandler,
    launchRouteHandler,
    loginRouteHandler,
    secureLTISession,
    } from '@lti-tool/hono';
    import { MemoryStorage } from '@lti-tool/memory';

    // Generate keypair (use proper key management in production)
    const keyPair = await crypto.subtle.generateKey(
    {
    name: 'RSASSA-PKCS1-v1_5',
    modulusLength: 2048,
    publicExponent: new Uint8Array([1, 0, 1]),
    hash: 'SHA-256',
    },
    true,
    ['sign', 'verify'],
    );

    const ltiConfig = {
    stateSecret: new TextEncoder().encode('your-secret-key'),
    keyPair,
    storage: new MemoryStorage(),
    };

    const ltiTool = new LTITool(ltiConfig);

    // Add your LMS configuration
    const clientId = await ltiTool.addClient({
    name: 'Moodle Sandbox',
    clientId: 'your-client-id-from-moodle',
    iss: 'https://sandbox.moodledemo.net',
    jwksUrl: 'https://sandbox.moodledemo.net/mod/lti/certs.php',
    authUrl: 'https://sandbox.moodledemo.net/mod/lti/auth.php',
    tokenUrl: 'https://sandbox.moodledemo.net/mod/lti/token.php',
    });

    await ltiTool.addDeployment(clientId, {
    deploymentId: 'your-deployment-id-from-moodle',
    name: 'Default Deployment',
    });

    const app = new Hono();

    // Add LTI routes
    app.get('/lti/jwks', jwksRouteHandler(ltiConfig));
    app.post('/lti/launch', launchRouteHandler(ltiConfig));
    app.post('/lti/login', loginRouteHandler(ltiConfig));

    // Protect routes with LTI session
    app.use('/protected/*', secureLTISession(ltiConfig));

    app.get('/protected/content', (c) => {
    const session = c.get('ltiSession');
    return c.json({ message: `Hello ${session.user.name}` });
    });

    Optimized for serverless with impressive performance metrics

    Operation Execution Time
    Login/JWKS 3-5ms
    Launch (heaviest) 12-15ms
    Average 6.5ms
    Package Description Use Case
    @lti-tool/core Core LTI 1.3 implementation Required for all setups
    @lti-tool/hono Hono framework integration Serverless APIs
    @lti-tool/dynamodb DynamoDB storage adapter Production AWS deployments
    @lti-tool/memory In-memory storage adapter Development and testing

    Pluggable storage system supports multiple backends

    • Memory - Development and testing
    • DynamoDB - Production AWS (with caching)
    • PostgreSQL - Coming soon
    • MySQL - Coming soon
    • Custom - Implement the LTIStorage interface
    • Hono - Primary target (serverless-optimized)
    • TanStack - Planned
    • Fastify - Planned
    • Astro - Planned
    • Express - Planned

    Test your implementation with the public Moodle sandbox

    1. Go to Site AdministrationPluginsActivity modulesExternal toolManage tools
    2. Click "configure a tool manually"
    3. Fill in the configuration
    Field Value
    Tool name lti-tool
    Tool URL https://your-domain.com
    LTI version LTI 1.3
    Public key type Keyset URL
    Public keyset https://your-domain.com/lti/jwks
    Login URL https://your-domain.com/lti/login
    Redirection URI(s) https://your-domain.com/lti/launch
    1. Enable services

      • IMS LTI Assignment and Grade Services: Use this service for grade sync
      • IMS LTI Names and Role Provisioning: Use this service to retrieve members
      • Tool Settings: Use this service
    2. Set privacy options (optional)

      • Share launcher's name: Always
      • Share launcher's email: Always

    After saving, click the magnifying glass to view tool details and update your code

    const clientId = await ltiTool.addClient({
    name: 'Moodle Sandbox',
    clientId: 'YOUR_CLIENT_ID_FROM_MOODLE', // Copy from tool details
    iss: 'https://sandbox.moodledemo.net',
    jwksUrl: 'https://sandbox.moodledemo.net/mod/lti/certs.php',
    authUrl: 'https://sandbox.moodledemo.net/mod/lti/auth.php',
    tokenUrl: 'https://sandbox.moodledemo.net/mod/lti/token.php',
    });

    await ltiTool.addDeployment(clientId, {
    deploymentId: 'YOUR_DEPLOYMENT_ID_FROM_MOODLE', // Copy from tool details
    name: 'Default Deployment',
    });
    1. Edit any course
    2. Add activity → External tool
    3. Select your configured tool
    4. Test the launch!

    Production-ready security features

    • JWT Signature Verification - Using platform JWKS
    • Nonce Validation - Prevents replay attacks
    • State Verification - CSRF protection
    • Client ID Validation - Ensures proper tool targeting
    • Deployment Verification - Validates deployment context
    • Cookie-Free Design - Works in all iframe contexts, immune to 3rd party cookie restrictions

    Production Note: The quick start example uses crypto.subtle.generateKey() for simplicity. In production, use proper key management (AWS Parameter Store SecureString, AWS KMS, HashiCorp Vault, etc.).

    Examples repository coming soon. Watch this repo for updates!

    We welcome contributions! Please see our Contributing Guide for details.

    Need help? Open an issue or start a discussion