TypeScript + npm
If you want type safety, autocomplete, and access to the full SDK type definitions, you can install the JSA SDK via npm and write your extension in TypeScript.
This tutorial covers the basics — getting types working so your editor helps you write correct code. It doesn’t prescribe a specific bundler or build pipeline, since that depends on your project’s needs.
What you’ll need
Section titled “What you’ll need”- Node.js (v18+) and npm
- A text editor with TypeScript support (VS Code recommended)
- Access to the SketchUp for Web JSA Server
Step 1: Set up your project
Section titled “Step 1: Set up your project”mkdir my-jsa-extensioncd my-jsa-extensionnpm init -ynpm install @sketchup/sketchup-js-api@latest --save-devCreate a tsconfig.json:
{ "compilerOptions": { "target": "ES2020", "module": "ESNext", "moduleResolution": "bundler", "strict": true, "outDir": "./dist" }, "include": ["src/**/*"]}Step 2: Write your extension
Section titled “Step 2: Write your extension”Create src/main.ts:
import { SketchUpApi } from '@sketchup/sketchup-js-api';
await SketchUpApi.connect();
const model = await SketchUpApi.getActiveModel();const entities = await model.getActiveEntities();
console.log(`Model has ${entities.length} entities`);
// TypeScript knows exactly what methods are available:await model.performOperation('Create geometry', async (op) => { const face = await op.addFace([ [0, 0, 0], [100, 0, 0], [100, 100, 0], [0, 100, 0], ]); await face.pushPull(50);});Your editor will give you autocomplete for every method, type-check your parameters, and flag errors before you run anything.
Step 3: Build and deploy
Section titled “Step 3: Build and deploy”How you build depends on your setup. The simplest approach is TypeScript’s own compiler:
npx tscThis produces JavaScript in dist/. You can then serve those files with a local server or bundle them into a zip.
Two manifests: dev and production
Section titled “Two manifests: dev and production”A common pattern is to maintain two manifests:
manifest.dev.json — Points at your local server for development:
{ "manifestFormatVersion": "1.0.0", "id": "my-extension-dev", "name": "My Extension (Dev)", "baseUrl": "https://localhost:9000/", "mainFile": "index.html", "window": { "type": "floating" }, "commands": { "open": { "title": "My Extension (Dev)" } }, "menuItems": [{ "type": "item", "commandId": "open" }]}manifest.json — Points at your deployed URL for production:
{ "manifestFormatVersion": "1.0.0", "id": "my-extension", "name": "My Extension", "baseUrl": "https://your-server.example.com/my-extension/", "mainFile": "index.html", "window": { "type": "floating" }, "commands": { "open": { "title": "My Extension" } }, "menuItems": [{ "type": "item", "commandId": "open" }]}During development, zip and install the dev manifest. For production, zip your built files with the production manifest and deploy to your server (or upload to Extension Manager).
What’s next?
Section titled “What’s next?”- Set up a local HTTPS server: Local Development
- See the remote hosting pattern: HelloRemote example
- Browse the API reference for full type documentation