job-scout
v1.2.0
Published
TypeScript-native job-scout library
Maintainers
Readme
job-scout · 
TypeScript-first job scraping library with stable support for LinkedIn, Indeed, Bayt, and Naukri, plus experimental support for ZipRecruiter, Glassdoor, Google Jobs, and BDJobs.
Install
npm install job-scoutNode >=20 is required.
Quick Start
import { scoutJobs } from 'job-scout'
const jobs = await scoutJobs(
{
sites: ['indeed', 'linkedin', 'google'],
query: 'software engineer',
location: 'Ambon, Indonesia',
pagination: { limitPerSite: 20 },
filters: { postedWithinHours: 72 },
google: {
query: 'software engineer jobs near Ambon, Indonesia since yesterday',
},
indeed: { country: 'indonesia' },
enrichment: { enabled: true, mode: 'low' },
linkedin: {
fetchDescription: true,
enrichment: {
fields: { emails: true, skills: true },
exposeMeta: true,
},
},
},
{
transport: {
timeoutMs: 20_000,
},
experimental: {
experimentalSites: {
google: true,
},
},
logging: {
level: 'warn',
},
},
)
console.log(jobs.length)
console.log(jobs[0])Client API
import { createClient } from 'job-scout'
const client = createClient({
transport: { timeoutMs: 20_000 },
logging: { level: 'warn' },
})
const jobs = await client.scoutJobs({
sites: ['indeed'],
query: 'backend engineer',
location: 'Austin, TX',
indeed: { country: 'usa' },
})Public API
createClient(config?: JobScoutConfig): JobScoutClientscoutJobs(request: JobSearchRequest, config?: JobScoutConfig): Promise<Job[]>scoutJobRows(request: JobSearchRequest, config?: JobScoutConfig): Promise<JobRow[]>toJobRows(jobs: Job[]): JobRow[]
Request Model
JobSearchRequest supports:
sites: JobSite[](required, non-empty)- Stable by default:
indeed | linkedin | bayt | naukri - Experimental (opt-in required):
zipRecruiter | glassdoor | google | bdjobs
- Stable by default:
query?: stringlocation?: stringpagination?: { limitPerSite?: number; offset?: number }filters?: { distanceMiles?: number; remote?: boolean; easyApply?: boolean; employmentType?: ...; postedWithinHours?: number }enrichment?: EnrichmentConfiglinkedin?: { fetchDescription?: boolean; companyIds?: number[]; enrichment?: EnrichmentConfig }indeed?: { country?: string }google?: { query?: string }
EnrichmentConfig supports:
enabled?: boolean(defaultfalse)mode?: 'off' | 'low' | 'medium' | 'high'budget?: { maxExtraRequestsPerJob?: number; maxPagesPerDomain?: number; requestTimeoutMs?: number }sources?: { jobDetailPage?: boolean; externalApplyPage?: boolean; companyPages?: boolean }fields?: { emails?: boolean; skills?: boolean; seniority?: boolean; companyWebsite?: boolean; workMode?: boolean; companySize?: boolean }exposeMeta?: boolean(defaultfalse, addsjob.enrichmentMeta)
Constraint rules are enforced at compile time (TypeScript) and runtime:
- Experimental sites must be explicitly enabled with
config.experimental.experimentalSites.<site> = true. - If
sitesincludesgoogle,google.queryis required. - For Indeed, use only one filter group at a time:
filters.postedWithinHoursfilters.easyApplyfilters.employmentType/filters.remote
- For LinkedIn,
filters.postedWithinHoursandfilters.easyApplycannot both be enabled.
Configuration
JobScoutConfig:
transport: proxies, user agent, CA cert path, timeoutperformance: global/site concurrency, retry policy, adaptive concurrencyexperimental:{ experimentalSites: Record<Site, boolean> }(partial overrides allowed; missing keys default tofalse)output: description format, salary annualization, salary fallback behaviorlogging:error | warn | info | debug
Testing
Unit tests:
bun run testLive integration tests:
JOBSCOUT_TEST_PROXIES="host1:port1,host2:port2" \
bun run test:integration:liveFull suite:
bun run test:allRelease
This package is published through GitHub Actions using npm trusted publishing (OIDC).
Publish a new version
- Update the version in
package.json. - Commit and push the version change.
- Create and push a matching tag:
git tag v<package-version>
git push origin v<package-version>The publish workflow verifies that v<package-version> exactly matches package.json and then runs:
bun run typecheckbun run testbun run buildnpm publish --provenance --access public
