How to Perform Multi-Market Job Searches Using linkedin-search and freehire-search
Both linkedin-search and freehire-search are zero-dependency Bun CLI tools that enable multi-market job discovery—LinkedIn via HTML scraping with textual location flags and Freehire via JSON API with geographic facets—allowing you to target multiple countries and regions from a single codebase.
The ai-job-search repository by MadsLorentzen provides specialized command-line interfaces for automated job discovery across global markets. By combining these two tools, you can execute comprehensive multi-market job searches without external dependencies, API keys, or complex configuration files.
Architecture of the Search Tools
Both tools share a uniform zero-dependency architecture built for the Bun runtime. According to SETUP.md (lines 80-100), neither requires npm install beyond dev types; they run using only Bun's built-in fetch and string handling.
linkedin-search (located at .agents/skills/linkedin-search/cli/src/cli.ts) scrapes LinkedIn's public "jobs-guest" HTML endpoints and extracts job fields using regex helpers. It handles markets through free-text location strings.
freehire-search (located at .agents/skills/freehire-search/cli/src/cli.ts) queries the structured JSON API of freehire.me using facet-based geographic filters. The API returns normalized data, eliminating the need for HTML parsing.
Configuring Market Parameters for LinkedIn Searches
LinkedIn searches accept market specifications through the --location (or -l) flag. As defined in .agents/skills/linkedin-search/SKILL.md (lines 50-52), this flag receives a textual place string such as "Berlin, Germany" or "Remote", which is sent directly to LinkedIn's guest endpoint.
To filter by workplace type, use the --remote flag (line 53). The CLI supports three output formats: json (default), table, and plain.
Example searches across different markets:
# Search for "data engineer" in Berlin, Germany
bun run .agents/skills/linkedin-search/cli/src/cli.ts \
search -q "data engineer" -l "Berlin, Germany" --format table
# Same query for remote markets
bun run .agents/skills/linkedin-search/cli/src/cli.ts \
search -q "data engineer" -l "Remote" --remote remote --format table
Configuring Market Parameters for Freehire Searches
Freehire searches utilize structured facet flags to define markets without parsing ambiguity. According to .agents/skills/freehire-search/SKILL.md (lines 88-99), you can target specific geographic levels using:
--region(e.g.,eu,na)--country(e.g.,US,DE)--city
Additional filters include --seniority, --category, --skill, and --remote (lines 93-97). This facet approach allows you to target entire continents or specific municipalities with equal precision.
Example multi-market configurations:
# Senior backend roles in the EU region
bun run .agents/skills/freehire-search/cli/src/cli.ts \
search -q "backend engineer" --seniority senior --region eu --format table
# Remote React jobs in the United States
bun run .agents/skills/freehire-search/cli/src/cli.ts \
search -q "react" --remote remote --country US --format table
# DevOps positions in Germany posted in the last 14 days
bun run .agents/skills/freehire-search/cli/src/cli.ts \
search --category devops --country DE --jobage 14 --format table
Combining Tools for Comprehensive Multi-Market Coverage
To perform a true multi-market job search, combine both tools in a single script or Bash loop. Because linkedin-search accepts arbitrary location strings while freehire-search uses standardized facets, you can cover overlapping geographic regions using complementary approaches.
The following example searches LinkedIn across three specific cities while using Freehire to cover the entire EU region:
LOCATIONS=("Berlin, Germany" "London, United Kingdom" "Remote")
for loc in "${LOCATIONS[@]}"; do
echo "=== LinkedIn results for $loc ==="
bun run .agents/skills/linkedin-search/cli/src/cli.ts \
search -q "machine learning" -l "$loc" --format table
done
echo "=== Freehire results for EU ==="
bun run .agents/skills/freehire-search/cli/src/cli.ts \
search -q "machine learning" --region eu --format table
This approach leverages LinkedIn for granular city-level searches and Freehire for broad regional coverage, maximizing your multi-market job search reach.
Workflow Integration and Automation
Both tools integrate automatically with the repository's /scrape workflow. The workflow discovers each skill under .agents/skills/*/SKILL.md and executes its search command when enabled: true is set, requiring no additional glue code.
Important compliance note: As documented in .agents/skills/linkedin-search/SKILL.md (lines 29-33), automated bulk scraping violates LinkedIn's Terms of Service. Keep request volumes low and for personal use only. The Freehire service (lines 20-24) is publicly accessible, unauthenticated, and intended for personal use without API key requirements.
Summary
- Both tools are zero-dependency Bun CLIs requiring no external libraries or API keys.
- LinkedIn uses free-text
--locationflags for market targeting, scraping HTML from public endpoints. - Freehire uses structured facet flags (
--region,--country,--city) to query a normalized JSON API. - Combine approaches using Bash scripts to search specific cities via LinkedIn and broad regions via Freehire.
- Integrate with the
/scrapeworkflow by enabling skills in their respectiveSKILL.mdfiles. - Respect TOS by limiting LinkedIn scrape volumes to personal use only.
Frequently Asked Questions
Do I need API keys to use linkedin-search and freehire-search?
No. Neither tool requires API keys or authentication tokens. linkedin-search scrapes public LinkedIn HTML endpoints, while freehire-search queries the public freehire.me JSON API. Both use Bun's native fetch implementation without external dependencies.
How do I search multiple countries simultaneously?
For LinkedIn, create a Bash loop iterating over location strings (e.g., "Paris, France", "Tokyo, Japan"). For Freehire, use broad facet flags like --region eu to cover multiple countries in one query, or chain multiple --country flags if the CLI supports repeated arguments. The tools are designed to run sequentially in scripts for comprehensive coverage.
What output formats are supported by both tools?
Both linkedin-search and freehire-search support three identical output formats: json (default), table, and plain. Specify your preferred format using the --format flag in any search command.
Are these tools suitable for production or commercial use?
No. According to the source code in .agents/skills/linkedin-search/SKILL.md (lines 29-33), automated scraping of LinkedIn violates their Terms of Service and should be limited to low-volume personal use. Freehire is also intended for personal use (lines 20-24). Neither tool should be deployed for commercial data harvesting or high-frequency automated job aggregation.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →