Lesson 1: Introduction & Setup
Simplest Architecture

We use a widely adopted, high-performance, and deployment-friendly architecture commonly favored by backend developers for building and deploying microservices.
- The entire Picoflow application runs on NestJS/NodeJS with Docker, and can be deployed to any cloud environment or self-hosted infrastructure.
- We use NoSQL databases such as MongoDB, DocumentDB, or CosmosDB to manage session data.
- Consuming clients interact with a single
/runendpoint, supplying different flow parameters and receiving a fully customizable response.
Before we start
Before we start building, let’s make sure you have the right tools for the job.
- Download Node.js v20 or above. I use nvm
- install Node.js
nvm install v20
- If you prefer to use a desktop version of MongoDB,
- download the MongoDB docker
- download deskop MongoDB Compass
- If you prefer to use local Cosmo Emulator
- Or you can use Cloud MongoDB, AWS DocumentDB, Azure Cosmo
Install the picoflow framework libary
- For now , you will be given a picoflow.tgz
- do a
$ npm i picoflow.tgz
- in the future, it will be able to install from corporate npm registries
Using and installing Nestjs
The reason we chose Nestjs as or first supported tech-stack is it is arguably the best JS framework for building backend services.
$ npm i -g @nestjs/cli
$ nest new my-flow
You will see the following in our my-flow directory:
src
├── tutorial.controller.ts <--rename from app.controller.ts
├── app.module.ts
├── app.service.ts
└── main.ts
Let's rename app.controller.ts to tutorial.controller.ts
app.module.ts
Also, creae a HealthController , Cloud deployment will need it to keep Kubernetes Pods alive.
import { Controller, Get, HttpCode, HttpStatus } from '@nestjs/common';
@Controller('healthcheck')
export class HealthController {
@Get()
@HttpCode(HttpStatus.OK)
check() {
return { status: 'ok', timestamp: new Date().toISOString() };
}
}
The most important thing now is to import FlowModule.
We are showing the local file form for now instead of using import {} from @picoflow, for simplicity sake.
We also import the configuration module provided by NestJS to read values from .env or environmental variables.
import { Module } from '@nestjs/common';
import { FlowModule } from './flow.module';
import { ConfigModule } from '@nestjs/config';
import { HealthController } from './controllers/health-controller';
import { TutorialController } from './controllers/tutorial-controller';
@Module({
imports: [FlowModule, ConfigModule],
controllers: [TutorialController, HealthController],
})
export class AppModule {}
main.ts
- NodeJS and NestJS has a standard
main.tsfile that can be configured with a variety of options such as middlewares. - Nest is built such that it can use
ExpressorFastify(a successor) as its underlying HTTP engine. - I use
Fastifyhere because it is more modern with many improvements aboveExpress. - I also configure the
Swaggerfor auto API documentation.
import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { AppModule } from './app.module';
import {
FastifyAdapter,
NestFastifyApplication,
} from '@nestjs/platform-fastify';
async function bootstrap() {
const app = await NestFactory.create<NestFastifyApplication>(
AppModule,
new FastifyAdapter(),
);
// Create Swagger document
const config = new DocumentBuilder()
.setTitle('Chat Flow API')
.setDescription('API documentation for Chat Flow')
.setVersion('1.0')
.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api', app, document);
await app.listen(8000, '0.0.0.0');
}
bootstrap();
npm dependencies
You may need the common JS packages below. After that you can do a yarn install or npm install
"dependencies": {
"@anatine/zod-nestjs": "^2.0.10",
"@anatine/zod-openapi": "^2.2.7",
"@azure/cosmos": "^4.2.0",
"@fastify/cors": "^10.0.1",
"@fastify/static": "6",
"@langchain/anthropic": "^1.0.0",
"@langchain/core": "1.0.2",
"@langchain/google-genai": "^1.0.0",
"@langchain/ollama": "^1.0.0",
"@langchain/openai": "^1.0.0",
"@nestjs/common": "^10.4.7",
"@nestjs/config": "^4.0.1",
"@nestjs/core": "^10.4.7",
"@nestjs/jwt": "^10.2.0",
"@nestjs/passport": "^10.0.3",
"@nestjs/platform-fastify": "^10.4.7",
"@nestjs/serve-static": "^4.0.2",
"@nestjs/swagger": "^8.0.2",
"dotenv": "^16.4.5",
"langchain": "1.0.2",
"moment": "^2.30.1",
"mongodb": "^6.14.1",
"reflect-metadata": "^0.2.0",
"uuid": "^11.0.3",
"zod"}
Wrapping up
We’ve completed the routine setup. If you’re already familiar with NestJS, feel free to adjust the standard configuration as needed. Now we can shift our focus to the core code that demonstrates the key concepts and the advantages of using Picoflow.