Skip to main content
bamboohr-local-dev-loop Configure BambooHR local development with hot reload, mocking, and testing.
Use when setting up a development environment, configuring test workflows,
or establishing a fast iteration cycle with BambooHR API.
Trigger with phrases like "bamboohr dev setup", "bamboohr local development",
"bamboohr dev environment", "develop with bamboohr", "bamboohr mock".
Jump to install Skills Marketplace Discover and explore AI skills built by the community.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Copy promptShow prompt details A direct command skips the review prompt. Inspect the source before running it.
npx skills add https://github.com/jeremylongshore/claude-code-plugins-plus-skills --skill bamboohr-local-dev-loopThe command stays on one line. Scroll horizontally to inspect it before copying.
Prefer a local copy? Download the files currently available to SkillsMP.
Download Zip Downloading... More from this repository Implement user sign-up and sign-in flows with Clerk.
Use when building authentication UI, customizing sign-in experience,
or implementing OAuth social login.
Trigger with phrases like "clerk sign-in", "clerk sign-up",
"clerk login flow", "clerk OAuth", "clerk social login".
Implement session management and middleware with Clerk.
Use when managing user sessions, configuring route protection,
or implementing token refresh and custom JWT templates.
Trigger with phrases like "clerk session", "clerk middleware",
"clerk route protection", "clerk token", "clerk JWT".
Configure enterprise SSO, role-based access control, and organization management.
Use when implementing SSO integration, configuring role-based permissions,
or setting up organization-level controls.
Trigger with phrases like "clerk SSO", "clerk RBAC",
"clerk enterprise", "clerk roles", "clerk permissions", "clerk organizations".
Related occupations SOC
Based on SOC occupation classification
name bamboohr-local-dev-loop description Configure BambooHR local development with hot reload, mocking, and testing.
Use when setting up a development environment, configuring test workflows,
or establishing a fast iteration cycle with BambooHR API.
Trigger with phrases like "bamboohr dev setup", "bamboohr local development",
"bamboohr dev environment", "develop with bamboohr", "bamboohr mock".
allowed-tools Read, Write, Edit, Bash(npm:*), Bash(pnpm:*), Grep version 1.4.0 license MIT author Jeremy Longshore <jeremy@intentsolutions.io> tags ["saas","hr","bamboohr","development"] compatibility Designed for Claude Code
BambooHR Local Dev Loop
Overview
Set up a fast, reproducible local development workflow for BambooHR integrations with request mocking, hot reload, and integration testing against the real API.
Prerequisites
Completed bamboohr-install-auth setup
Node.js 18+ with npm or pnpm
BAMBOOHR_API_KEY and BAMBOOHR_COMPANY_DOMAIN set in .env
Instructions
Step 1: Project Structure
my-bamboohr-project/
โโโ src/
โ โโโ bamboohr/
โ โ โโโ client.ts # Reusable API client
โ โ โโโ types.ts # BambooHR response types
โ โ โโโ employees.ts # Employee operations
โ โโโ index.ts
โโโ tests/
โ โโโ mocks/
โ โ โโโ bamboohr.ts # API response fixtures
โ โโโ unit/
โ โ โโโ employees.test.ts
โ โโโ integration/
โ โโโ bamboohr.test.ts
โโโ .env.local # Real API key (git-ignored)
โโโ .env.example # Template for team
โโโ .env.test # Test config (sandbox key)
โโโ package.json
Step 2: Create Reusable API Client
import 'dotenv/config' ;
export class BambooHRClient {
private baseUrl : string ;
private authHeader : string ;
constructor (companyDomain ?: string , apiKey ?: string ) {
const domain = companyDomain || process.env .BAMBOOHR_COMPANY_DOMAIN !;
const key = apiKey || process.env .BAMBOOHR_API_KEY !;
this .baseUrl = `https://api.bamboohr.com/api/gateway.php/${domain} /v1` ;
. = ;
}
request<T>( : , : = {}): <T> {
res = ( , {
...options,
: {
: . ,
: ,
: ,
...options. ,
},
});
(!res. ) {
errMsg = res. . ( ) || res. ;
(res. , errMsg, path);
}
res. () <T>;
}
( : | , : []): < < , >> {
. ( );
}
(): <{ : [] }> {
. ( );
}
}
{
( ) {
( );
. = ;
}
}
this
authHeader
`Basic ${Buffer.from (`${key} :x` ).toString('base64' )} `
async
path
string
options
RequestInit
Promise
const
await
fetch
`${this .baseUrl} ${path} `
headers
Authorization
this
authHeader
Accept
'application/json'
'Content-Type'
'application/json'
headers
if
ok
const
headers
get
'X-BambooHR-Error-Message'
statusText
throw
new
BambooHRError
status
return
json
as
Promise
async
getEmployee
id
number
string
fields
string
Promise
Record
string
string
return
this
request
`/employees/${id} /?fields=${fields.join(',' )} `
async
getDirectory
Promise
employees
BambooEmployee
return
this
request
'/employees/directory'
export
class
BambooHRError
extends
Error
constructor
public status : number , message : string , public path : string
super
`BambooHR ${status} : ${message} [${path} ]`
this
name
'BambooHRError'
Step 3: Setup Hot Reload and Scripts {
"scripts" : {
"dev" : "tsx watch src/index.ts" ,
"test" : "vitest run" ,
"test:watch" : "vitest --watch" ,
"test:integration" : "DOTENV_CONFIG_PATH=.env.test vitest run tests/integration/" ,
"typecheck" : "tsc --noEmit"
} ,
"devDependencies" : {
"tsx" : "^4.0.0" ,
"vitest" : "^2.0.0" ,
"typescript" : "^5.5.0" ,
"msw" : "^2.0.0"
}
}
Step 4: Mock BambooHR API with MSW
import { http, HttpResponse } from 'msw' ;
const MOCK_COMPANY = 'testcompany' ;
const BASE = `https://api.bamboohr.com/api/gateway.php/${MOCK_COMPANY} /v1` ;
export const bamboohrHandlers = [
http.get (`${BASE} /employees/directory` , () => {
return HttpResponse .json ({
fields : [{ id : 'displayName' , type : 'text' , name : 'Display Name' }],
employees : [
{
id : '1' , displayName : 'Jane Smith' , firstName : 'Jane' ,
lastName : 'Smith' , jobTitle : 'Engineer' , department : 'Engineering' ,
workEmail : 'jane@test.com' , location : 'Remote' ,
},
{
id : '2' , displayName : 'Bob Jones' , firstName : 'Bob' ,
lastName : 'Jones' , jobTitle : 'Designer' , department : 'Design' ,
workEmail : 'bob@test.com' , location : 'NYC' ,
},
],
});
}),
http.get (`${BASE} /employees/:id/` , ({ params } ) => {
return HttpResponse .json ({
id : params.id , firstName : 'Jane' , lastName : 'Smith' ,
jobTitle : 'Engineer' , department : 'Engineering' ,
hireDate : '2023-01-15' , workEmail : 'jane@test.com' ,
status : 'Active' ,
});
}),
http.post (`${BASE} /reports/custom` , () => {
return HttpResponse .json ({
title : 'Test Report' , employees : [
{ firstName : 'Jane' , lastName : 'Smith' , department : 'Engineering' },
],
});
}),
];
Step 5: Write Unit Tests
import { describe, it, expect, beforeAll, afterAll, afterEach } from 'vitest' ;
import { setupServer } from 'msw/node' ;
import { bamboohrHandlers } from '../mocks/bamboohr' ;
import { BambooHRClient } from '../../src/bamboohr/client' ;
const server = setupServer (...bamboohrHandlers);
beforeAll (() => server.listen ({ onUnhandledRequest : 'error' }));
afterEach (() => server.resetHandlers ());
afterAll (() => server.close ());
describe ('BambooHRClient' , () => {
const client = new BambooHRClient ('testcompany' , 'fake-key' );
it ('fetches the employee directory' , async () => {
const dir = await client.getDirectory ();
expect (dir.employees ).toHaveLength (2 );
expect (dir.employees [0 ].displayName ).toBe ('Jane Smith' );
});
it ('fetches a single employee' , async () => {
const emp = await client.getEmployee (1 , ['firstName' , 'lastName' , 'jobTitle' ]);
expect (emp.firstName ).toBe ('Jane' );
expect (emp.jobTitle ).toBe ('Engineer' );
});
});
Step 6: Integration Test Against Real API
import { describe, it, expect } from 'vitest' ;
import { BambooHRClient } from '../../src/bamboohr/client' ;
const HAS_KEY = !!process.env .BAMBOOHR_API_KEY ;
describe.skipIf (!HAS_KEY )('BambooHR Integration' , () => {
const client = new BambooHRClient ();
it ('should fetch the real employee directory' , async () => {
const dir = await client.getDirectory ();
expect (dir.employees .length ).toBeGreaterThan (0 );
expect (dir.employees [0 ]).toHaveProperty ('displayName' );
}, 15_000 );
});
Output
Reusable BambooHRClient with typed methods
MSW mocks for offline development
Unit tests with mocked API
Integration tests gated on BAMBOOHR_API_KEY presence
Hot-reload dev server via tsx watch
Error Handling Error Cause Solution BambooHRError 401Wrong key in .env.local Re-copy from BambooHR dashboard MSW onUnhandledRequest Unmocked endpoint hit Add handler to bamboohrHandlers ECONNREFUSED in testsMSW server not started Ensure beforeAll(() => server.listen()) Slow integration tests Real API latency Increase vitest timeout to 15s
Resources
Next Steps See bamboohr-sdk-patterns for production-ready code patterns.