Customer tracking for React apps — without client-side scripts
Most customer tracking tools inject browser scripts that hurt performance, raise GDPR concerns, and miss server-side events. TinyCRM takes the opposite approach: call it from your backend when things actually happen — sign-ups, upgrades, key actions — not from a script watching mouse movements.
Where TinyCRM lives in a React architecture
React is a UI library — it renders UI in the browser. Your customer data and business events live in your backend. That's where TinyCRM belongs.
React App (browser)
└── fetch("/api/auth/signup", { email, password })
│
▼
Your Node.js Backend (Express / Fastify / etc.)
├── Create user in PostgreSQL
├── Generate session token
└── tinycrm.identify({ email, status: "free" })
│
▼
TinyCRM Dashboard (your customer table)React only knows about your backend API — it never talks to TinyCRM directly. This means no extra bundle size, no browser permission requirements, and no CORS headaches.
Installation
Install on your backend server, not in the React app itself.
npm install tinycrm-sdkGetting started: React + Express backend
A typical setup for Vite React with a separate Express API server.
Step 1 — Initialize the SDK on your Express server
// server/lib/tinycrm.ts
import { TinyCRM } from "tinycrm-sdk";
export const tinycrm = new TinyCRM({
apiKey: process.env.TINYCRM_API_KEY!,
});Step 2 — Call identify() in your sign-up route
// server/routes/auth.ts
import express from "express";
import { tinycrm } from "../lib/tinycrm";
import { db } from "../lib/db";
const router = express.Router();
router.post("/signup", async (req, res) => {
const { email, name, password } = req.body;
const user = await db.users.create({ email, name, password });
// Fire-and-forget — won't delay the response
tinycrm.identify({
email: user.email,
name: user.name,
status: "free",
params: { signup_source: req.headers.referer ?? "direct" },
});
res.json({ ok: true, userId: user.id });
});
export default router;Step 3 — Track paid conversions
// server/routes/webhooks.ts
router.post("/webhooks/payment", async (req, res) => {
const { email, plan } = verifyPaymentWebhook(req);
tinycrm.identify({
email,
status: "paid",
params: { plan },
});
res.sendStatus(200);
});Step 4 — Use with React Query for real-time UI updates
// components/SignupForm.tsx — React component (client side)
// This calls YOUR backend, not TinyCRM directly
import { useMutation } from "@tanstack/react-query";
function SignupForm() {
const signup = useMutation({
mutationFn: async (data: { email: string; name: string }) => {
const res = await fetch("/api/auth/signup", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data),
});
return res.json();
},
});
return (
<form onSubmit={(e) => {
e.preventDefault();
signup.mutate({ email: "...", name: "..." });
}}>
{/* form fields */}
</form>
);
}Step 5 — Serverless function variant (AWS Lambda)
// functions/signup.ts
import { TinyCRM } from "tinycrm-sdk";
const tinycrm = new TinyCRM({
apiKey: process.env.TINYCRM_API_KEY!,
});
export const handler = async (event: AWSEvent) => {
const { email, name } = JSON.parse(event.body!);
// ... create user in DB ...
// TinyCRM identify — fire and forget
tinycrm.identify({ email, name, status: "free" });
return { statusCode: 200, body: JSON.stringify({ ok: true }) };
};Why server-side tracking beats client-side for React apps
Zero bundle impact
The SDK never ships to the browser. Your React bundle stays lean, Lighthouse scores unaffected.
No ad blockers
Server-to-server HTTP calls are never blocked by browser extensions or content blockers.
GDPR-friendly
No third-party scripts loading in the user's browser. You control exactly what data is sent.
Works offline users
Captures events even if the user has JavaScript disabled or navigates away immediately.
React FAQ
Can I import tinycrm-sdk in a React component?
No. tinycrm-sdk is a server-side SDK. Import it only in your Node.js backend — Express routes, serverless functions, or BFF (backend-for-frontend) servers. Your React components should call your own API, which then calls TinyCRM.
I'm using Vite + React with a separate Express backend. Where do I call identify()?
In your Express route handlers. For example, in your POST /auth/signup handler, after creating the user in your database, call tinycrm.identify(). The frontend never touches TinyCRM directly.
What if my React app uses serverless functions (AWS Lambda, Netlify Functions)?
Perfect. Call identify() inside your serverless function handler. The SDK is compatible with all Node.js 18+ environments including Lambda, Netlify Functions, Vercel Functions, and Cloudflare Workers.
Know your React app customers
14-day free trial. No credit card. 10-minute integration.
npm install tinycrm-sdk