Modules & Workspaces
Loopstack uses NestJS modules to organize your application and workspaces to expose workflows in the Studio UI.
Modules
A module groups related workflows, tools, and services together.
Basic Module
import { Module } from '@nestjs/common';
import { ClaudeModule } from '@loopstack/claude-module';
import { LoopCoreModule } from '@loopstack/core';
import { MyTool } from './tools/my.tool';
import { MyWorkflow } from './workflows/my.workflow';
@Module({
imports: [LoopCoreModule, ClaudeModule],
providers: [MyWorkflow, MyTool],
exports: [MyWorkflow, MyTool],
})
export class MyFeatureModule {}Key Rules
- Always import
LoopCoreModule— provides core framework functionality - Import feature modules like
ClaudeModulefor AI,SandboxToolModulefor Docker sandboxes, etc. - Documents are NOT providers — they are plain DTOs and don’t need registration
- Export workflows and tools that other modules might need
Registering in AppModule
Add your module to the main AppModule:
import { Module } from '@nestjs/common';
import { DefaultWorkspace } from './default.workspace';
import { MyFeatureModule } from './my-feature/my-feature.module';
@Module({
imports: [MyFeatureModule],
providers: [DefaultWorkspace],
})
export class AppModule {}Multi-Module Example
For larger applications, split functionality across modules:
// analytics.module.ts
@Module({
imports: [LoopCoreModule, ClaudeModule],
providers: [AnalyticsWorkflow, DataFetchTool],
exports: [AnalyticsWorkflow],
})
export class AnalyticsModule {}
// notifications.module.ts
@Module({
imports: [LoopCoreModule],
providers: [NotificationWorkflow, EmailTool],
exports: [NotificationWorkflow],
})
export class NotificationsModule {}
// app.module.ts
@Module({
imports: [AnalyticsModule, NotificationsModule],
providers: [DefaultWorkspace],
})
export class AppModule {}Workspaces
A workspace is an organizational container that groups related workflows together and makes them visible in the Loopstack Studio interface.
Basic Workspace
import { Injectable } from '@nestjs/common';
import { InjectWorkflow, Workspace, WorkspaceInterface } from '@loopstack/common';
import { AnalyticsWorkflow } from './analytics/analytics.workflow';
import { ChatWorkflow } from './chat/chat.workflow';
@Injectable()
@Workspace({
config: {
title: 'Customer Analytics',
description: 'Data analysis and reporting workflows',
},
})
export class AnalyticsWorkspace implements WorkspaceInterface {
@InjectWorkflow() analyticsWorkflow: AnalyticsWorkflow;
@InjectWorkflow() chatWorkflow: ChatWorkflow;
}Hidden Workflows
Workflows used only as sub-workflows (not directly by users) can be hidden from the sidebar:
@Workspace({ config: { title: 'My Workspace' } })
export class DefaultWorkspace implements WorkspaceInterface {
@InjectWorkflow() mainWorkflow: MainWorkflow;
@InjectWorkflow({ options: { visible: false } })
helperWorkflow: HelperWorkflow;
}Workspace YAML (Optional)
You can define workspace metadata in a separate YAML file:
@Workspace({
configFile: __dirname + '/analytics.workspace.yaml',
})
export class AnalyticsWorkspace implements WorkspaceInterface { ... }# analytics.workspace.yaml
type: workspace
title: 'Customer Analytics'
description: 'Data analysis and reporting workflows'Registering Workspaces
Workspaces are registered as providers in the AppModule:
@Module({
imports: [MyFeatureModule],
providers: [AnalyticsWorkspace],
})
export class AppModule {}Using in Loopstack Studio
Once registered:
- Open Loopstack Studio at
http://localhost:5173 - Your workspace appears in the sidebar
- Click a workflow to create a new run
- Fill in the input form and start the workflow
Registry References
- chat-example-workflow — Example module with LoopCoreModule and ClaudeModule imports
- custom-tool-example-module — Module with custom tools, services, and workflow providers
- run-sub-workflow-example — Module registering both parent and sub-workflow providers
Last updated on