Setup Appwrite Project
Step 1 — Create an Appwrite Project
- Go to cloud.appwrite.io and sign up / log in
- Create a new project (e.g. "Neutter")
- Copy your Project ID from the project settings
Step 2 — Create a Storage Bucket
- In the Appwrite console, go to Storage → Create Bucket
- Name it something like
files - Set permissions:
- For now, allow
Anyto read (so files can be viewed) - Allow
Anyto create (your server will upload on behalf of users)
- For now, allow
- Copy the Bucket ID
Step 3 — Get an API Key
- Go to Settings → API Keys → Create API Key
- Give it Storage permissions (read, write, delete)
- Copy the API Key
Setup NestJS Project
Step 1 — Create project
npm i-g @nestjs/cli
nest new backend
cd backend
Step 2 — Create Storage Module
nest g module AppwriteService
nest g service AppwriteService
nest g controller AppwriteService
Step 3 — Install the SDK
npm install node-appwrite
npm install multer
npm install --save-dev @types/multer
Step 4 — Add to your .env
APPWRITE_ENDPOINT=https://cloud.appwrite.io/v1
APPWRITE_PROJECT_ID=your-project-id
APPWRITE_API_KEY=your-api-key
APPWRITE_BUCKET_ID=your-bucket-id
Step 4 — Configure Appwrite SDK
// src/appwrite/appwrite.service.ts
import { Injectable } from '@nestjs/common';
import { Client, Storage } from 'node-appwrite';
@Injectable()
export class AppwriteService {
private client: Client;
private storage: Storage;
constructor() {
this.client = new Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Replace with your Appwrite endpoint
.setProject('<PROJECT_ID>') // Replace with your project ID
.setKey('<API_KEY>'); // Replace with your API key
this.storage = new Storage(this.client);
}
// add below wpload function here
}
Step 5 — Create Upload function
async uploadFile(file: Express.Multer.File) {
try {
const result = await this.storage.createFile(
process.env.APPWRITE_BUCKET_ID!,
ID.unique(),
InputFile.fromBuffer(file.buffer, file.originalname) // wraps buffer + filename
);
const fileUrl = `${process.env.APPWRITE_ENDPOINT}/storage/buckets/${process.env.APPWRITE_BUCKET_ID}/files/${result.$id}/preview?project=${process.env.APPWRITE_PROJECT_ID}`;
return {
message: 'File uploaded successfully',
fileId: result.$id,
url: fileUrl,
};
} catch (error) {
throw new InternalServerErrorException('Failed to upload file');
}
}
Step 6 — Setup Controller
import {
Controller,
Post,
UploadedFile,
UseInterceptors,
} from '@nestjs/common';
import { AppwriteServiceService } from './appwrite-service.service';
import { FileInterceptor } from '@nestjs/platform-express';
@Controller('appwrite-service')
export class AppwriteServiceController {
constructor(
private readonly appwriteService: AppwriteService,
) {}
@Post('upload')
@UseInterceptors(FileInterceptor('file'))
async uploadFile(@UploadedFile() file: Express.Multer.File) {
console.log("file dta:", file)
return this.appwriteServiceService.uploadFile(file);
}
}
Step 7 — Setup Configuration
Depending on the environment, different configuration settings should be used.
npm i --save @nestjs/config
Now in app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { AppwriteServiceModule } from './appwrite-service/appwrite-service.module';
import { ConfigModule } from '@nestjs/config';
@Module({
imports: [
ConfigModule.forRoot({ // add this part
isGlobal: true,
}),
AppwriteServiceModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
Step 8 — Test is using postman
Final Thoughts
Integrating Appwrite Storage with NestJS gives you a clean, scalable way to manage files without dealing with infrastructure complexity.
With just a few steps, you now have:
- File upload API
- Secure storage
- File preview links
Integrating Appwrite Storage with NestJS is a practical and efficient way to handle file management in your backend applications. With just a few configurations, you can offload complex storage logic and focus more on building core features.
Using Appwrite not only simplifies file handling but also provides scalability, security, and ease of use — making it an excellent choice for modern full-stack development.

Top comments (0)