Motia Icon
Core Concepts

Overview

One primitive, any language, event-driven by default - that's Motia

Motia is a backend framework built around a single core primitive: everything is a Step.

Want an API? That's a Step.
Need a background job? That's a Step.
Scheduled task? Also a Step.

Write each Step in whatever language makes sense - TypeScript, Python, or JavaScript. They all run together, share the same state, and talk through events.

How It Works

Every Step is just a file with two parts:

1. Config → When and how it runs
2. Handler → What it does

steps/my-step.step.ts
import { ApiRouteConfig, Handlers } from 'motia'
 
// Config - when it runs
export const config: ApiRouteConfig = {
  name: 'MyStep',
  type: 'api',
  path: '/endpoint',
  method: 'POST',
  emits: ['task.done']
}
 
// Handler - what it does
export const handler: Handlers['MyStep'] = async (req, { emit, logger }) => {
  logger.info('Processing request')
  
  await emit({
    topic: 'task.done',
    data: { result: 'success' }
  })
  
  return { status: 200, body: { success: true } }
}

👉 Drop this file in your steps/ folder and Motia finds it automatically. No registration, no imports, no setup.

Learn more about Steps →


Event-Driven Architecture

Steps don't call each other. They emit and subscribe to events.

This means:

  • Your API can trigger a background job without waiting for it
  • Steps run independently and retry on failure
  • You can add new Steps without touching existing ones
  • Everything is traceable from start to finish

Example: An API emits an event, a background Step picks it up:

// API Step emits
await emit({ topic: 'user.created', data: { email } })
 
// Event Step subscribes and processes
config = {
  type: 'event',
  subscribes: ['user.created']
}

That's it. No coupling, no dependencies.


Project Structure & Auto-Discovery

Motia automatically discovers Steps - no manual registration required.

Basic Structure

config.yml
.env
package.json
requirements.txt
tsconfig.json

The steps/ directory is the heart of your Motia application. All your workflow logic lives here, and Motia automatically discovers any file following the naming pattern.

Auto-Discovery Rules

Motia scans the steps/ directory and automatically registers files that:

  1. Match naming pattern:

    • TypeScript: .step.ts
    • JavaScript: .step.js
    • Python: _step.py (note: underscore before step)
  2. Export a config object with Step configuration

  3. Export a handler function with business logic

No imports. No registration. Just create the file and Motia finds it.


Multi-Language Support

Every Step can be in a different language. They all run in the same process and share everything.

Currently Supported:

  • TypeScript.step.ts
  • Python_step.py
  • JavaScript.step.js

Coming Soon:

  • Ruby → .step.rb
  • C# → .step.cs
  • Go → .step.go
  • And many more...

Example project:

api-endpoint.step.ts
ml-inference_step.py
send-email.step.js

All three Steps work together. TypeScript API emits an event → Python processes with ML → JavaScript sends the result.


Core Concepts

State Management

Persistent key-value storage that works across all Steps and languages.

await state.set('users', 'user-123', { name: 'John' })
const user = await state.get('users', 'user-123')

Learn about State →

Real-Time Streams

Push live updates to connected clients (browsers, mobile apps).

await streams.notifications.set('user-123', 'notif-1', {
  message: 'Order shipped!',
  timestamp: new Date().toISOString()
})

Clients receive updates instantly.

Learn about Streams →

Context Object

Every handler gets a context object with everything you need:

PropertyWhat It Does
loggerStructured logging
emitTrigger other Steps
statePersistent storage
streamsReal-time updates
traceIdRequest tracing

Development Tool - Workbench

create-pet

Visual interface for testing APIs, building and debugging flows:

  • See your entire flow as a beautiful diagram
  • Test API endpoints in the browser
  • Watch logs in real-time
  • Inspect state as it changes

Learn about Workbench →


What's Next?

Need help? See our Community Resources for questions, examples, and discussions.

On this page