Universal JavaScript/TypeScript SDK + CLI Tool for Tachles Link
npm install @tachles/linkbash
npm install @tachles/link
`
---
๐ง Quick Start
$3
Run the CLI tool to authenticate and configure your project:
`bash
npx link init
`
Interactive Setup:
1. Enter your Mothership URL
2. Enter your Application Name
3. Paste your User Master Key
4. Choose auto-activate or manual approval
Two Provisioning Flows:
- Auto-Activate (Recommended for development): Instant credentials without dashboard approval
- Manual Approval: Requires dashboard confirmation before receiving credentials
The CLI will create a .env file with your credentials automatically.
$3
`typescript
import { Link } from "@tachles/link/node";
// Automatically loads from .env and initializes!
const link = new Link();
// Track custom events - works immediately
await link.track("user_signup", { userId: "123", plan: "pro" });
// Capture exceptions
try {
// your code
} catch (error) {
await link.captureException(error);
}
`
$3
Next.js App Router (app/layout.tsx):
`tsx
import { TachlesLink } from "@tachles/link/react";
export default function RootLayout({ children }) {
return (
{children}
host={process.env.NEXT_PUBLIC_LINK_HOST}
appId={process.env.NEXT_PUBLIC_LINK_APP_ID}
debug={false}
/>
);
}
`
Vite/CRA:
`tsx
import { TachlesLink } from "@tachles/link/react";
function App() {
return (
<>
host={import.meta.env.VITE_LINK_HOST}
appId={import.meta.env.VITE_LINK_APP_ID}
/>
>
);
}
`
$3
`tsx
import { useTachlesLink } from "@tachles/link/react";
function MyComponent() {
const { track } = useTachlesLink(
process.env.NEXT_PUBLIC_LINK_HOST,
process.env.NEXT_PUBLIC_LINK_APP_ID
);
const handleClick = () => {
track("button_clicked", { buttonId: "cta-main" });
};
return ;
}
`
---
๐ Environment Variables
After running npx link init, these variables are added to your .env:
`env
LINK_HOST=https://link.tachles.dev
LINK_APP_ID=x-link-id-value
LINK_APP_SECRET=lk_app_secret_value
`
$3
Prefix with NEXT_PUBLIC_ (Next.js) or VITE_ (Vite) to make them available client-side:
`env
NEXT_PUBLIC_LINK_HOST=https://link.tachles.dev
NEXT_PUBLIC_LINK_APP_ID=x-link-id-value
`
Security Note: Never expose LINK_APP_SECRET to the client. React SDK only needs host and appId.
---
๐ API Reference
$3
#### Link Class
Constructor:
`typescript
new Link(config?: Partial, debug?: boolean)
`
Methods:
- start(): Initialize telemetry, send boot event, start heartbeat
- track(event: string, payload?: object): Track custom events
- captureException(error: Error): Send error to Mothership
Configuration:
`typescript
interface LinkConfig {
host?: string;
appId?: string;
appSecret?: string;
}
`
$3
#### Component
Props:
`typescript
interface TachlesLinkProps {
host?: string;
appId?: string;
debug?: boolean;
}
`
#### useTachlesLink() Hook
`typescript
const { track } = useTachlesLink(host, appId);
track(event: string, payload?: object);
`
---
๐ Security
- Node.js: Uses LINK_APP_SECRET for authenticated requests
- React: Only uses LINK_APP_ID (public identifier)
- All network requests are wrapped in error handlers
- SDK never crashes your application
---
๐ ๏ธ Development
$3
`bash
npm run build
`
$3
`bash
npm run typecheck
`
$3
`bash
npm run dev
`
---
๐ Package Structure
`
@tachles/link
โโโ /node # Node.js runtime
โโโ /react # React runtime
โโโ CLI (npx link) # Initialization tool
`
Exports:
- @tachles/link/node - Server-side SDK
- @tachles/link/react - Client-side React component
---
๐งช Testing
The SDK is designed to be resilient:
- All API calls are wrapped in try/catch
- Failed requests log warnings but don't throw
- Heartbeat continues even if individual requests fail
---
๐ License
MIT
---
๐ค Support
- Documentation: link.tachles.dev/docs
- Issues: GitHub Issues
- Email: support@tachles.dev
---
๐ฏ Telemetry Events
$3
- boot: Sent on startup
- heartbeat: Sent every 60s with system metrics
- shutdown: Sent on graceful exit
$3
- page_view: Sent on component mount
- session_end: Sent on visibility change
- page_unload: Sent before page unload
$3
- custom: Track any event via track() or useTachlesLink().track()
- error: Capture exceptions via captureException()`