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
Fully Implemented LTI 1.3 Specification:
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
LTIStorage interfaceTest your implementation with the public Moodle sandbox
| 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 |
Enable services
Set privacy options (optional)
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',
});
Production-ready security features
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