Expose Backend
Goal
Turn a JavaScript module into a remotely callable backend service using Graftcode Gateway - no controllers, no REST routes, no OpenAPI specs needed.
What You'll See
- Create a small JavaScript module with public methods.
- Host it through Graftcode Gateway using Docker.
- Explore the exposed methods in Graftcode Vision - your service is now accessible from any app as a strongly-typed client.
Prerequisites
- Docker installed and running
- Node.js only if you run the npm consumer locally - Docker alone is enough to build and host the service
Step 1. Create a project folder
Create a new folder and initialize a Node.js project:
mkdir js-energy-service cd js-energy-service npm init -y
Step 2. Write a JavaScript module with public methods
Create a file index.js:
class EnergyPriceCalculator { static getPrice() { return Math.floor(Math.random() * 5) + 100; } } module.exports = { EnergyPriceCalculator };
This is a plain JavaScript class - no decorators, no frameworks, no special annotations. Any public method you write here will automatically become available for remote consumption once hosted through Graftcode Gateway.
Step 3. Host it with Graftcode Gateway
Create a Dockerfile in the project root:
FROM node:24 WORKDIR /usr/app COPY . /usr/app/ RUN apt-get update \ && apt-get install -y wget \ && wget -O /usr/app/gg.deb https://github.com/grft-dev/graftcode-gateway/releases/latest/download/gg_linux_amd64.deb \ && dpkg -i /usr/app/gg.deb \ && rm /usr/app/gg.deb \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* EXPOSE 80 EXPOSE 81 CMD ["gg", "./package.json"]
The key line is the last one - gg (Graftcode Gateway) reads your package.json, discovers all public methods in your module, and exposes them automatically. Port 80 handles service calls, port 81 serves Graftcode Vision.
The Dockerfile base image is node:24, but Gateway analyzes and runs the module with its embedded Node.js 22 runtime. Stick to syntax and dependencies that work on Node 22 unless you have verified otherwise. During analysis Gateway may also log a logger re-initialization warning (last-write-wins); it is safe to ignore if the module loads successfully.
Build and run the container:
docker build --no-cache --pull -t myenergyservice-js:test . docker run -d -p 80:80 -p 81:81 --name graftcode_demo_js myenergyservice-js:test
Your JavaScript service is now running and exposed through Graftcode Gateway.
Step 4. Explore the service in Graftcode Vision
Open http://localhost:81/GV in your browser.
You will see all public methods from your JavaScript module - their names, parameter types, and return types. Graftcode Vision also provides:
- A "Try it out" button to call methods live, directly from the browser.
- A package manager command (npm, NuGet, PyPI, etc.) to install this service as a strongly-typed client in any other application.
Step 5. Run with a Project Key (recommended for real-world usage)
Everything above works without any account - perfect for learning and local development. When you're ready for real-world usage, create a free account at portal.graftcode.com, set up a project, and copy its Project Key.
Then pass the key when starting your gateway:
CMD ["gg", "./package.json", "--projectKey", "YOUR_PROJECT_KEY"]
A Project Key gives you:
- Stable registry URL - consumers always find and update your Graft through a permanent address, so install commands don't change when you redeploy.
- Portal visibility - see all your gateways and exposed services in one place at gateways.graftcode.com.
- Access control - decide who can download your Grafts using package manager authentication and permissions.
- MCP endpoint - Graftcode Gateway automatically exposes an MCP (Model Context Protocol) endpoint alongside your service, making your methods callable by AI agents and LLM-based tools out of the box.
Step 6. Call it from another app
Your service is now accessible from any application. From Graftcode Vision, select your target package type - for example npm - and copy the generated install command. That installs a Graft: a strongly-typed client that lets any app call your service methods directly.
Use the package name from Vision or Gateway logs (for this sample typically @graft/npm-js-energy-service):
const { EnergyPriceCalculator } = require("@graft/npm-js-energy-service"); const price = await EnergyPriceCalculator.getPrice(); console.log(price);
No REST clients, no request/response models, no endpoint URLs in your code. When you add or update a public method, consumers update their Graft with a single package manager command.