Motia Icon
Core Concepts

Overview

Build production-grade backends with a single primitive - APIs, background jobs, workflows, and AI agents unified

Build production-grade backends with a single primitive.

Motia is a unified backend framework that combines APIs, background jobs, durable workflows, AI agents, streaming, and observability around one core primitive: the 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 queued messages.

How It Works

Every Step is just a file with two parts:

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

src/my-step.step.ts
import { type Handlers, type StepConfig } from 'motia'
 
export const config = {
  name: 'MyStep',
  description: 'Handles incoming requests',
  triggers: [
    { type: 'api', path: '/endpoint', method: 'POST' },
  ],
  enqueues: ['task.done'],
  flows: ['my-flow'],
} as const satisfies StepConfig
 
export const handler: Handlers<typeof config> = async (req, { enqueue, logger }) => {
  logger.info('Processing request')
 
  await enqueue({
    topic: 'task.done',
    data: { result: 'success' }
  })
 
  return { status: 200, body: { success: true } }
}

Drop this file in your src/ 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 enqueue messages to topics that other Steps consume.

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 enqueues a message, a queue Step picks it up:

// API Step enqueues
await enqueue({ topic: 'user.created', data: { email } })
 
// Queue Step triggers on the topic
config = {
  triggers: [
    { type: 'queue', topic: '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 src/ 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 src/ 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 (install with pip install motia-python)
  • 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 enqueues a message, Python processes with ML, JavaScript sends the result.


Core Concepts

State Management

Persistent key-value storage that works across all Steps and languages. state.set returns { new_value, old_value }.

const result = await state.set('users', 'user-123', { name: 'John' })
// result = { new_value: { name: 'John' }, old_value: null }
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

Adapters

Pluggable infrastructure components that enable horizontal scaling and custom implementations. Swap default file-based storage with Redis, RabbitMQ, or your own implementations without changing your code.

Learn about Adapters

Context Object

Every handler gets a context object with everything you need:

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

Development Tool - iii Development Console

Visual interface for building and debugging flows:

  • See your entire flow as a beautiful diagram
  • Watch logs in real-time
  • Inspect state as it changes
  • View stream updates in real-time

Learn about the iii development console


What's Next?

On this page