A self-hosted web application that converts STL mesh files to STEP (ISO 10303) solid format. Built for makers, engineers, and 3D printing enthusiasts who need to work with CAD software that requires STEP files.
The Problem: You download an STL file from Thingiverse, Printables, or another repository. You want to modify it in Fusion 360, SolidWorks, or FreeCAD — but those programs work best with STEP files, not meshes.
The Solution: This tool converts your STL files to STEP format through a simple drag-and-drop web interface. It runs entirely on your own hardware with no file size limits, no subscriptions, and no uploads to third-party servers.
This tool converts STL meshes to STEP format, but it does not reverse-engineer parametric geometry. Here's what that means:
| What You Get | What You Don't Get |
|---|---|
| ✅ Valid STEP file importable into any CAD software | ❌ Editable features (fillets, chamfers, extrudes) |
| ✅ Solid body you can boolean with other geometry | ❌ Smooth curves (cylinders remain faceted) |
| ✅ Repaired mesh (holes filled, normals fixed) | ❌ Reduced file size |
| ✅ Ability to add new parametric features around it | ❌ Parametric editing history |
This is still useful because most CAD software handles STEP bodies better than raw meshes for boolean operations, sectioning, and adding new features on top of existing geometry.
- 🖱️ Drag & Drop Interface — Upload files with a simple drag-and-drop or file picker
- 👁️ Real-Time 3D Preview — Inspect your STL in-browser with Three.js before converting
- 🔧 Automatic Mesh Repair — Fixes non-manifold edges, holes, duplicate vertices, and inconsistent normals
- ⚙️ Adjustable Tolerance — Control the precision of edge merging (trade accuracy for speed)
- 📦 Batch Processing — Upload and convert multiple files at once
- ❌ Job Cancellation — Cancel queued or in-progress conversions
- 📊 Job Queue Dashboard — Monitor conversion progress with Bull Board
- 🧹 Auto Cleanup — Files automatically expire and are deleted after 24 hours (configurable)
- 💓 Health Monitoring — Built-in system health checks
- 🔒 Self-Hosted — Your files never leave your network
- 🐳 Docker Ready — One-command deployment
- Docker installed
- Docker Compose installed
# Clone the repository
git clone https://github.com/voron69-bit/Stepifi.git
cd Stepifi
# Start the application
docker-compose up -d
# Check logs to verify startup
docker-compose logs -fWait until you see:
Redis connected
Server running on port 3169
Then open your browser to http://localhost:3169
The Docker setup consists of two containers managed by Docker Compose:
| Container | Purpose |
|---|---|
| app | Node.js application server + FreeCAD conversion engine |
| redis | Job queue storage and session management |
| Component | Purpose |
|---|---|
| Debian Bookworm | Base operating system |
| Node.js 20 | Application runtime |
| FreeCAD 0.21.2 (headless) | STL → STEP conversion engine |
| Python 3 + NumPy | Mesh processing operations |
| Express.js | Web server and API |
| BullMQ | Job queue management |
| Port | Service | URL |
|---|---|---|
3169 |
Main web interface | http://localhost:3169 |
| Volume | Purpose |
|---|---|
uploads |
Temporary storage for uploaded STL files |
converted |
Storage for converted STEP files |
redis_data |
Redis persistence (survives container restarts) |
Navigate to http://localhost:3169 (or your server's IP/domain).
- Drag and drop an STL file onto the upload zone, OR
- Click the upload zone to browse for a file
Multiple files can be uploaded for batch processing.
Hover over the info icons (ⓘ) for detailed explanations.
| Setting | Description | Default |
|---|---|---|
| Tolerance | Edge merging precision. Lower = more accurate but slower. Higher = faster but less precise. | 0.01 |
| Repair Mesh | Attempts to fix common mesh issues (holes, bad normals, non-manifold edges) before conversion. | Enabled |
A 3D preview appears immediately showing:
- Interactive view (drag to rotate, scroll to zoom, right-click to pan)
- Vertex count
- Face count
- File size
Use the toolbar buttons to:
- 🔄 Reset camera view
- ⊞ Toggle wireframe mode
Each uploaded file creates a job card showing:
- Status: Queued → Processing → Completed (or Failed)
- Progress bar: Visual progress indicator
- Time remaining: Countdown until auto-deletion (24 hours default)
Job Controls:
- Cancel — Stop queued or processing jobs
- Download — Get your STEP file when complete
- Delete — Remove job and files
Once status shows Completed, click the green Download STEP button.
The file will download with the same name as your original STL, but with a .step extension.
Click the heartbeat icon (💓) in the top-right header to verify system status:
- Overall system health
- Redis connection status
- FreeCAD availability
- FreeCAD version information
Or via API:
curl http://localhost:3169/healthResponse:
{
"status": "healthy",
"redis": true,
"freecad": true,
"freecadVersion": "FreeCAD 0.21.2, Libs: 0.21.2..."
}Create a .env file or modify docker-compose.yml:
| Variable | Default | Description |
|---|---|---|
PORT |
3169 |
Web interface port |
BULL_BOARD_PORT |
3001 |
Queue dashboard port |
MAX_FILE_SIZE |
104857600 |
Max upload size in bytes (100MB) |
JOB_TTL_HOURS |
24 |
Hours before files auto-delete |
CLEANUP_CRON |
*/15 * * * * |
Cleanup frequency (every 15 min) |
DEFAULT_TOLERANCE |
0.01 |
Default conversion tolerance |
RATE_LIMIT_MAX |
20 |
Max requests per 15 minutes |
MAX_CONCURRENT_JOBS |
2 |
Simultaneous conversions |
In docker-compose.yml:
environment:
- MAX_FILE_SIZE=524288000Then restart:
docker-compose down && docker-compose up -dIn docker-compose.yml:
ports:
- "8080:3169" # Access at http://localhost:8080
- "8081:3001" # Dashboard at http://localhost:8081curl -X POST http://localhost:3169/api/convert \
-F "[email protected]" \
-F "tolerance=0.01" \
-F "repair=true"Response:
{
"success": true,
"jobId": "e96d23f0-cdf5-42f3-b787-aaa70bb55ed2",
"message": "Conversion job queued",
"expiresAt": "2024-12-10T15:30:00.000Z"
}curl http://localhost:3169/api/job/{jobId}Response:
{
"success": true,
"job": {
"id": "e96d23f0-cdf5-42f3-b787-aaa70bb55ed2",
"status": "completed",
"progress": 100,
"message": "Conversion complete",
"result": {
"outputPath": "/app/converted/e96d23f0-cdf5-42f3-b787-aaa70bb55ed2.step",
"facets": 19568,
"outputSize": 14308580
},
"expiresIn": 86340
}
}curl -O http://localhost:3169/api/download/{jobId}curl -X DELETE http://localhost:3169/api/job/{jobId}Response:
{
"success": true,
"message": "Job deleted successfully"
}# Check logs for errors
docker-compose logs app
docker-compose logs redis
# Rebuild containers
docker-compose down
docker-compose build --no-cache
docker-compose up -dFreeCAD is baked into the Docker image. If you see this error:
docker-compose build --no-cache
docker-compose up -d- Use a higher tolerance value (e.g.,
0.05or0.1) - Simplify the mesh in MeshLab or Blender before uploading
- Increase Docker memory allocation in Docker Desktop settings
- Check
docker-compose logs appfor specific Python errors
Files auto-delete after JOB_TTL_HOURS (default 24 hours). Download promptly or increase the TTL in docker-compose.yml.
The API has rate limiting enabled (20 requests per 15 minutes by default). Wait or increase RATE_LIMIT_MAX in environment variables.
- Hard refresh your browser (Ctrl+F5 or Cmd+Shift+R)
- Check browser console (F12) for JavaScript errors
- Ensure you're using a modern browser (Chrome, Firefox, Edge, Safari)
docker-compose restart redis
docker-compose restart appPrerequisites:
- Node.js 18+
- Redis server
- FreeCAD with CLI (
freecadcmd)
Install FreeCAD:
Ubuntu/Debian:
sudo apt-get update && sudo apt-get install freecadmacOS:
brew install freecadWindows: Download from freecadweb.org
Run the Application:
# Install dependencies
npm install
# Start Redis (separate terminal)
redis-server
# Start the app in development mode
npm run devStepifi/
├── docker-compose.yml # Container orchestration
├── Dockerfile # App container build
├── package.json # Node.js dependencies
├── src/
│ ├── server.js # Express entry point
│ ├── config/
│ │ └── config.js # Environment configuration
│ ├── routes/
│ │ ├── api.routes.js # API endpoints
│ │ └── health.routes.js # Health check
│ ├── services/
│ │ ├── converter.service.js # FreeCAD integration
│ │ ├── queue.service.js # BullMQ job queue
│ │ ├── cleanup.service.js # Auto-cleanup cron
│ │ └── storage.service.js # File management
│ ├── middleware/
│ │ ├── upload.middleware.js # Multer file upload
│ │ └── rateLimiter.middleware.js # Rate limiting
│ └── scripts/
│ └── convert.py # FreeCAD Python conversion script
└── public/
├── index.html # Main web UI
├── logo.png # Application logo
├── css/
│ └── style.css # Styles
└── js/
└── app.js # Frontend JavaScript + Three.js
The Docker setup includes volume mounts for live development:
volumes:
- ./src:/app/src # Live source code updates
- ./public:/app/public # Live frontend updatesChanges to JavaScript, HTML, or CSS are reflected immediately. Just refresh your browser.
For changes to package.json, Dockerfile, or docker-compose.yml:
docker-compose down
docker-compose build
docker-compose up -d- Rate Limiting: Enabled by default (20 requests per 15 minutes)
- File Size Limits: 100MB by default (configurable)
- Auto-Cleanup: Files expire after 24 hours
- No Authentication: This tool has no built-in authentication. If exposing to the internet, use a reverse proxy with authentication (nginx, Caddy, Traefik)
- CORS: Disabled by default. Enable only if needed for external integrations.
# Use behind a reverse proxy with HTTPS
# Example nginx config:
server {
listen 443 ssl;
server_name stepifi.yourdomain.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://localhost:3169;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}- Increase tolerance to
0.05or0.1 - Disable mesh repair if the file is already clean
- Increase Docker memory allocation
- Increase
MAX_CONCURRENT_JOBSin environment variables - Monitor system resources to avoid overload
- Consider adding more Redis workers
- Default cleanup runs every 15 minutes
- Adjust
CLEANUP_CRONif you need more frequent cleanup - Monitor disk usage in the
uploadsandconverteddirectories
- No parametric data recovery: Output is a solid body, not editable features
- Faceted curves: Cylinders and curved surfaces remain as triangle meshes
- File size: Very large files (>1GB) may cause memory issues
- Processing time: Complex models can take several minutes
- Mesh quality: Output quality depends heavily on input STL quality
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Non-Commercial License — Free for personal, educational, and non-commercial use only
See LICENSE file for details.
- FreeCAD — Open-source CAD platform
- Three.js — WebGL 3D visualization
- BullMQ — Redis-based job queue
- Express.js — Web framework
- Inspired by Jaydenha09/STL-to-STEP-web-converter
- Issues: GitHub Issues
- Discussions: GitHub Discussions
Made with ❤️ for the maker community