Using Pendulum

Local Development

Developers can get started building applications with Pendulum by developing locally. Simply create a project directory with the build tool of choice, move into the new directory, and install the Pendulum CLI.

$ npm create vite@latest demo
$ cd demo
$ npm install @pendulum-baas/cli

Once the Pendulum CLI tool has been installed, running the init command installs the SDK and backend packages, and adds npm scripts for stopping and starting the backend.

The Pendulum SDK is easily incorporated into the frontend code with an import:

import { PendulumClient } from "@pendulum-baas/sdk";

const client = new PendulumClient();

// your frontend code...

Developers can take advantage of both the default CRUD operations built into Pendulum, as well as the real-time data subscription feature to make frontend applications reactive. Here we look at both features at work in a React project using JavaScript.

const loadItems = async () => {
  try {
    const response = await client.db.getAll("items");

    if (response.success) {
      setItems(response.data);
    } else {
      throw new Error(data.error);
    }
  } catch (error) {
    setError("Failed to fetch items");
    console.error(error);
  }
};
This function makes use of the db.getAll method to fetch all records from the items collection.
const updateItems = (message) => {
  const { action, eventData } = message;

  switch (action) {
    case "insert":
      setItems(prev => [...prev, ...eventData.affected]);
      break;

    case "update":
      setItems(prev => prev.map(p => {
        if (eventData.ids.includes(p.id)) {
          return eventData.affected.find(item => item.id === p.id);
        }
        return p;
      }));
      break;

    case "delete":
      setItems(prev => prev.filter(p => !eventData.ids.includes(p.id)));
      break;
  }
};
updateItems is the callback function that runs when the client receives an update from the Pendulum events server. Each message sent by the events server contains a field to indicate what type of database event took place. Developers can use this field to take different actions for each kind of mutation.
useEffect(() => {
  loadItems();

  client.realtime.subscribe("items", updateItems);

  return () => client.realtime.unsubscribe("items", updateItems);
}, []);
Invoke the loadItems function to get all items and register the updateItems function to handle real-time updates.

On mount, we can fetch the items from the backend with a GET request facilitated by the SDK client's getAll database method. In that same effect we also subscribe to the items collection, passing in the updateItems function as the callback. Now, every time the events server pushes an update to the client, the updateItems function runs and updates the frontend state.

Starting the Development Environment

The npx pendulum dev command initializes the local development environment.

At any point during the development process, the Pendulum backend container network can be stopped or started with the npm scripts that were added with the init command.

$ npm run pendulum-backend:start
$ npm run pendulum-backend:stop

The admin dashboard, available at http://localhost:3000/admin can now be used to manipulate backend data and visualize the flow of data through the application during local development. Additionally, developers can adjust collection-level permissions and observe these permission changes during runtime.

Production

When it's time to deploy an application, executing the deploy command will prompt developers for their AWS account information, the desired region for deployment, the project name, and the path to the directory with their frontend build artifacts. The CLI tool will automatically deploy those resources, alongside the entire Pendulum backend infrastructure, to a dedicated VPC in the developer's AWS account.

Deployments can be torn down and destroyed at any time with the destroy command. This command will delete AWS CloudFormation stack associated with the deployment.

AI-Powered Backend Insights

The MCP server is distributed as a separate npm package that connects your deployed Pendulum backend to AI agents. Install the package globally using npm install -g @pendulum-baas/mcp and configure your AI agent with data from your deployment:

{
  "mcpServers": {
    "pendulum": {
      "command": "pendulum-mcp",
      "args": [
        "--url",
        "<your-alb-url>",
        "--jwt-secret",
        "<your-jwt-secret>",
      ],
      "env": {
        "PATH": "<your-PATH-variable>",
      },
    },
  },
}

Once your Pendulum backend is deployed, the MCP server enables natural language interaction with your production systems through AI agents (e.g., Claude Desktop). After configuring the agent with your deployment’s ALB URL and JWT secret, you can monitor and debug your backend through simple, conversational queries.

Real-time System Monitoring

Developers can ask direct questions about their backend's current state:

  • "How many users are currently connected to my application?"
  • "Check the health status of my Pendulum services."
  • "Start monitoring my real-time events for the next 5 minutes."

Schema Management and Validation

The MCP server can analyze application data and help maintain consistency across collections:

  • "Generate schema as a JSON object for my products collection based on existing data."
  • "Which documents in my products collection don't match the expected schema?