Getting Started with de.sdk
Complete JavaScript/TypeScript SDK for building web applications on the De. platform.
What You'll Learn
This guide covers:
- Installing de.sdk in your project
- Basic initialization and configuration
- Your first map integration
- Making authenticated API calls
- Understanding SDK architecture
Time to complete: 15 minutes
Installation
Install via Package Manager
Add de.sdk to your project
npm install @de./sdkyarn add @de./sdkpnpm add @de./sdkInstall TypeScript (Optional)
For TypeScript projects
npm install --save-dev typescript @types/nodeThe SDK includes built-in TypeScript definitions.
Quick Start
Your First Map
HTML Setup
Create a container for the map
<!DOCTYPE html>
<html>
<head>
<title>De. SDK Demo</title>
<style>
#map {
width: 100%;
height: 600px;
}
</style>
</head>
<body>
<div id="map"></div>
<script type="module" src="/main.js"></script>
</body>
</html>Initialize MSI
Load the map interface
import De from '@de./sdk'
// Initialize the Map Service Interface
const msi = new De.MSI({
element: 'map',
accessToken: 'your-access-token'
})
// Load the map
const { controls, handles } = await msi.load()
console.log('Map loaded successfully!')Add Interactive Elements
Display locations and routes
// Add pickup location
await handles.pickupPoint(
{ lng: -74.0060, lat: 40.7128 },
{ label: 'Pickup Location' }
)
// Add delivery location
await handles.dropoffPoint(
{ lng: -73.9855, lat: 40.7580 },
{ label: 'Delivery Location' }
)
// The SDK automatically creates a route between pickup and delivery!SDK Architecture
Core Modules
MSI - Map Service Interface
Complete map integration with routing, navigation, and real-time tracking
Learn more →DClient - Order Management
Create and manage orders, track packages, handle delivery workflows
Learn more →MSI Architecture Layers
The Map Service Interface provides three layers of abstraction:
1. Controls (Promise-based)
Direct, granular control over map operations.
// Get current location
const location = await controls.getCurrentLocation()
// Search for a place
const results = await controls.searchQuery('Times Square')
// Set route
await controls.setRoute({
origin: { lng: -74.0060, lat: 40.7128 },
destination: { lng: -73.9855, lat: 40.7580 }
})Use when: You need precise control over individual operations.
2. Handles (Stream-based)
High-level, stream-based API for common workflows.
// Track user location continuously
const myLocationStream = await handles.myLocation()
myLocationStream.live(async (controls) => {
console.log('Location updated!')
})
// Track peer location (e.g., delivery driver)
const driverStream = await handles.peerLocation(
{ lng: -74.0060, lat: 40.7128 },
{ label: 'Driver' }
)
driverStream.live(async (controls) => {
// Update driver position
await controls.move({
position: newDriverLocation
})
})Use when: You need stream-based updates or common patterns.
3. Plugins (Extensibility)
Create custom extensions with full SDK access.
const myPlugin = {
name: 'analytics',
async install(sdk, options) {
// Access controls, handles, utils
const { controls, handles, utils } = sdk
// Track all route creations
controls.on('route:created', (route) => {
analytics.track('Route Created', route)
})
}
}
const msi = new De.MSI({
element: 'map',
accessToken: token,
plugins: [myPlugin]
})Use when: You need custom behavior or third-party integrations.
Authentication & Access
Get Access Token
From your De. workspace dashboard
Navigate to Settings → API Keys and generate a new access token.
Initialize Access
For making authenticated API calls
import De from '@de./sdk'
const access = new De.Access({
workspace: 'your-workspace-id',
accessToken: 'your-access-token',
env: 'prod' // or 'dev', 'staging'
})
// Make authenticated requests
const user = await access.request({
url: '/user',
method: 'GET'
})
console.log('User:', user.data)Use with MSI
Pass access token to map initialization
const msi = new De.MSI({
element: 'map',
accessToken: 'your-access-token'
})Configuration Options
MSI Configuration
const msi = new De.MSI({
// Required
element: 'map', // Container element ID
accessToken: 'token', // Your access token
// Optional
mapEngine: 'mapbox', // 'mapbox' or 'google'
mapStyle: 'streets', // Map style theme
center: { lng: -74.0060, lat: 40.7128 }, // Initial center
zoom: 12, // Initial zoom level
// Advanced
plugins: [], // Custom plugins
locale: 'en', // Language
units: 'metric', // 'metric' or 'imperial'
// Debug
debug: true // Enable debug logging
})Access Configuration
const access = new De.Access({
// Required
workspace: 'workspace-id', // Your workspace ID
accessToken: 'token', // Access token
// Optional
env: 'prod', // Environment: 'dev', 'staging', 'prod'
apiUrl: 'custom-url', // Custom API URL
timeout: 30000, // Request timeout (ms)
retries: 3 // Auto-retry failed requests
})TypeScript Support
The SDK includes complete TypeScript definitions:
import De, {
MSIControls,
MSIHandles,
DClientOrder,
Location,
Route
} from '@de./sdk'
// Fully typed
const controls: MSIControls = await msi.getControls()
const location: Location = await controls.getCurrentLocation()
// Type-safe order creation
const order: DClientOrder = await dclient.orders.create({
type: 'delivery',
pickup: { /* ... */ },
delivery: { /* ... */ }
})Framework Integration
React
import { useEffect, useRef } from 'react'
import De from '@de./sdk'
function MapComponent() {
const mapRef = useRef<HTMLDivElement>(null)
const msiRef = useRef<any>(null)
useEffect(() => {
const initMap = async () => {
msiRef.current = new De.MSI({
element: mapRef.current!,
accessToken: process.env.REACT_APP_DE_ACCESS_TOKEN
})
await msiRef.current.load()
}
initMap()
return () => {
msiRef.current?.destroy()
}
}, [])
return <div ref={mapRef} style={{ width: '100%', height: '600px' }} />
}Vue 3
<template>
<div ref="mapContainer" style="width: 100%; height: 600px"></div>
</template>
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
import De from '@de./sdk'
const mapContainer = ref<HTMLDivElement | null>(null)
let msi: any = null
onMounted(async () => {
msi = new De.MSI({
element: mapContainer.value!,
accessToken: import.meta.env.VITE_DE_ACCESS_TOKEN
})
await msi.load()
})
onUnmounted(() => {
msi?.destroy()
})
</script>Next.js
'use client'
import { useEffect, useRef } from 'react'
import dynamic from 'next/dynamic'
// Dynamically import to avoid SSR issues
const MapComponent = dynamic(() => Promise.resolve(() => {
const mapRef = useRef<HTMLDivElement>(null)
useEffect(() => {
import('@de./sdk').then(async ({ default: De }) => {
const msi = new De.MSI({
element: mapRef.current!,
accessToken: process.env.NEXT_PUBLIC_DE_ACCESS_TOKEN
})
await msi.load()
})
}, [])
return <div ref={mapRef} style={{ width: '100%', height: '600px' }} />
}), { ssr: false })
export default MapComponentCommon Patterns
Track Delivery in Real-time
// Initialize map
const msi = new De.MSI({
element: 'map',
accessToken: token
})
const { handles } = await msi.load()
// Set delivery route
await handles.pickupPoint(pickupCoords, { label: 'Restaurant' })
await handles.dropoffPoint(deliveryCoords, { label: 'Customer' })
// Track driver
const driverStream = await handles.peerLocation(
initialDriverPosition,
{ label: 'Driver', icon: 'car' }
)
// Update driver position (from WebSocket/API)
socket.on('driver:location', (position) => {
driverStream.live(async (controls) => {
await controls.move({ position })
})
})Create and Track Order
import De from '@de./sdk'
const access = new De.Access({
workspace: workspaceId,
accessToken: token
})
// Create order
const order = await access.request({
url: '/orders',
method: 'POST',
body: {
type: 'delivery',
pickup: { /* ... */ },
delivery: { /* ... */ },
items: [/* ... */]
}
})
// Track order status
const socket = io('wss://api.dedot.io', {
auth: { token }
})
socket.emit('subscribe', {
channel: 'order',
id: order.data.id
})
socket.on('order:updated', (update) => {
console.log('Order status:', update.status)
})Error Handling
try {
const msi = new De.MSI({
element: 'map',
accessToken: token
})
await msi.load()
} catch (error) {
if (error.code === 'INVALID_TOKEN') {
// Handle authentication error
redirectToLogin()
} else if (error.code === 'ELEMENT_NOT_FOUND') {
// Handle missing container
console.error('Map container not found')
} else {
// Handle other errors
console.error('Map initialization failed:', error)
}
}Best Practices
Do's
- Store access tokens securely (env variables)
- Destroy MSI instances when unmounting
- Use TypeScript for type safety
- Handle errors gracefully
- Clean up event listeners
- Use appropriate zoom levels
Don'ts
- Don't hardcode access tokens
- Don't create multiple MSI instances per container
- Don't ignore errors
- Don't forget to clean up resources
- Don't expose tokens in client code
- Don't skip error boundaries

