{"id":51918448,"url":"https://github.com/microlinkhq/microlink","last_synced_at":"2026-07-27T14:30:41.065Z","repository":{"id":372784149,"uuid":"1285199376","full_name":"microlinkhq/microlink","owner":"microlinkhq","description":"The Microlink API organized into products, each returning a direct result","archived":false,"fork":false,"pushed_at":"2026-07-23T10:38:05.000Z","size":2517,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-07-23T11:09:23.635Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/microlinkhq.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-30T15:14:19.000Z","updated_at":"2026-07-23T10:07:13.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/microlinkhq/microlink","commit_stats":null,"previous_names":["microlinkhq/microlink"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/microlinkhq/microlink","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microlinkhq%2Fmicrolink","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microlinkhq%2Fmicrolink/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microlinkhq%2Fmicrolink/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microlinkhq%2Fmicrolink/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/microlinkhq","download_url":"https://codeload.github.com/microlinkhq/microlink/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microlinkhq%2Fmicrolink/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35897143,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-07-20T02:08:10.276Z","status":"online","status_checked_at":"2026-07-25T02:00:06.922Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-07-27T14:30:40.584Z","updated_at":"2026-07-27T14:30:41.041Z","avatar_url":"https://github.com/microlinkhq.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# microlink.io\n\n\u003e The [Microlink API](https://microlink.io) organized into products, each returning a direct result.\n\nTurning a page into markdown, taking a screenshot, or getting every link on a page shouldn't require hand-writing query parameters. This library organizes the Microlink API into products — the way Stripe organizes a powerful API into `stripe.customers.create()`:\n\n```js\nconst microlink = require('microlink.io')()\n\nmicrolink.markdown('https://example.com').then(markdown =\u003e {\n  console.log(markdown) // → the page content as a Markdown string\n})\n```\n\nIt's a thin layer over [@microlink/mql](https://github.com/microlinkhq/mql): HTTP, auth, retries, errors and binary handling are already solved there. Each product just sets the right API parameters and unwraps the result.\n\n## Install\n\n```bash\nnpm install microlink.io\n```\n\n## Usage\n\nThe export is a single factory. Call it once to get a client; the optional argument carries `apiKey` and any other client-wide defaults:\n\n```js\nconst createClient = require('microlink.io')\n\nconst microlink = createClient() // free client\nconst microlinkPro = createClient({ apiKey: process.env.MICROLINK_API_KEY }) // pro client\n```\n\nESM works the same way:\n\n```js\nimport createClient from 'microlink.io'\n\nconst microlink = createClient()\n```\n\nWhatever you pass to the factory is merged into every call, and per-call options can override it.\n\n### Passing options\n\nEvery product method takes a single options object: `product(url, options)`. The library routes each key to the right destination automatically:\n\n- `headers` travels as real HTTP request headers (never in the URL). The API forwards any `x-api-header-\u003cname\u003e` header to the target fetch as `\u003cname\u003e` — the right way to pass secrets like cookies.\n- Well-known capability keys nest under the product (for example `fullPage` for `screenshot`, `format` for `pdf`, `selector` for `markdown`).\n- Everything else goes as a top-level API query parameter (`device`, `waitUntil`, `prerender`, `ttl`, `proxy`, ...).\n\n```js\nconst microlink = require('microlink.io')()\n\nmicrolink.screenshot('https://example.com', {\n  fullPage: true, // nests under `screenshot`\n  device: 'iPhone 11' // top-level query param\n})\n```\n\n## Products\n\nEvery [microlink.io](https://microlink.io) product maps to a client method:\n\n| Product | Method |\n|---|---|\n| Link preview / Metadata | `metadata(url)` |\n| Markdown / HTML / Text | `markdown(url)` / `html(url)` / `text(url)` |\n| Screenshot | `screenshot(url)` |\n| Animated Screenshot | `screenshot(url, { animated: true })` |\n| PDF | `pdf(url)` |\n| Logo | `logo(url)` |\n| Embed | `embed(url)` |\n| Video / Audio | `video(url)` / `audio(url)` |\n| Lighthouse | `lighthouse(url)` |\n| Technologies | `technologies(url)` |\n| Search | `search(query)` |\n| Function | `run(url, code)` (alias `function`) |\n\nPlus library extras: `links` / `images` / `videos` / `audios` / `emails` collections and `extract` for custom data rules.\n\n### metadata(url, options)\n\nThe unified metadata object (title, description, image, publisher, ...):\n\n```js\nmicrolink.metadata('https://vercel.com').then(({ title, description }) =\u003e {\n  console.log(title, description)\n})\n```\n\n### markdown(url, options) / html(url, options) / text(url, options)\n\nThe page content as Markdown, HTML or plain text. Use `selector` to scope it:\n\n```js\nmicrolink.markdown('https://example.com', { selector: 'article' }).then(markdown =\u003e {\n  console.log(markdown)\n})\n```\n\n### screenshot(url, options)\n\nTakes a screenshot and returns the asset object (`url`, `type`, `width`, `height`, `size`, ...):\n\n```js\nmicrolink.screenshot('https://example.com', { fullPage: true }).then(({ url }) =\u003e {\n  console.log(url)\n})\n```\n\n### pdf(url, options)\n\nGenerates a PDF and returns the asset object:\n\n```js\nmicrolink.pdf('https://example.com', { format: 'A4' }).then(({ url }) =\u003e {\n  console.log(url)\n})\n```\n\n### logo(url, options)\n\nThe brand logo of the site. Pass `square: true` to prefer the square variant:\n\n```js\nmicrolink.logo('https://github.com', { square: true }).then(({ url }) =\u003e {\n  console.log(url)\n})\n```\n\n### embed(url, options)\n\nThe oEmbed-style embeddable iframe (`{ html, scripts }`), e.g. for a YouTube video or a Tweet. Constrain with `maxWidth`/`maxHeight`:\n\n```js\nmicrolink.embed('https://www.youtube.com/watch?v=dQw4w9WgXcQ').then(({ html }) =\u003e {\n  console.log(html)\n})\n```\n\n### video(url, options) / audio(url, options)\n\nThe primary video or audio of the page (e.g. the video of a Vimeo page or a Tweet), detected by the API and returned as the asset object:\n\n```js\nmicrolink.video('https://vimeo.com/76979871').then(({ url, type }) =\u003e {\n  console.log(url) // → direct .mp4 URL\n})\n```\n\n### links / images / videos / audios — (url, options)\n\nEvery media URL on the page as a clean `string[]` — absolute, junk-filtered and deduped. Scope with `selectorAll`:\n\n```js\nmicrolink.links('https://example.com', { selectorAll: 'nav a' }).then(links =\u003e {\n  console.log(links) // → ['https://example.com/docs', ...]\n})\n```\n\n### emails(url, options)\n\nEvery email address present on the page — from `mailto:` links and plain text alike. It's a preset over the API's `email` rule type, which extracts and validates addresses server-side:\n\n```js\nmicrolink.emails('https://microlink.io').then(emails =\u003e {\n  console.log(emails) // → ['hello@microlink.io']\n})\n```\n\n### extract(url, rules, options)\n\nCustom data rules with full [MQL rule grammar](https://microlink.io/docs/mql/getting-started/overview) parity — the same `data` rules object you'd write for raw MQL, with the result unwrapped:\n\n```js\nmicrolink.extract('https://microlink.io', {\n  image: { selector: 'meta[property=\"og:image\"]', attr: 'content', type: 'image' }\n}).then(({ image }) =\u003e {\n  console.log(image) // → { url, type, size, size_pretty, width, height }\n})\n```\n\nNested and array rules work the same way — every named product above is just a preset over this engine.\n\n### technologies(url, options) / lighthouse(url, options)\n\nThe tech stack behind a site, or a full Lighthouse report:\n\n```js\nmicrolink.technologies('https://microlink.io').then(technologies =\u003e {\n  console.log(technologies) // → [{ name: 'Cloudflare', ... }]\n})\n```\n\n### search(query, options)\n\nGoogle as structured data (via [@microlink/google](https://github.com/microlinkhq/google)) — built for agents, RAG pipelines, and anything that needs fresh Google results without parsing SERP HTML. Requires an `apiKey`. [Google search operators](https://ahrefs.com/blog/google-advanced-search-operators/) (`site:`, `filetype:`, quotes, ...) work as-is:\n\n```js\nmicrolink.search('Lotus Elise S2').then(page =\u003e {\n  console.log(page.results)\n  // → [{ title: 'Lotus Elise - Wikipedia', url, description }, ...]\n  console.log(page.knowledgeGraph) // entity card, when Google shows one\n  console.log(page.peopleAlsoAsk) // related questions\n  console.log(page.relatedSearches) // query expansion ideas\n})\n```\n\n`type` routes the query to any of the 10 Google verticals, each returning fields normalized for that surface:\n\n| `type` | Returns |\n|---|---|\n| `search` (default) | web results + knowledge graph, related questions/searches |\n| `news` | articles with `publisher`, `date`, thumbnail |\n| `images` | full-resolution image URLs with dimensions |\n| `videos` | video metadata with duration |\n| `places` / `maps` | local entities with address, phone, coordinates, ratings, hours |\n| `shopping` | products with parsed `price` and ratings |\n| `scholar` | papers with citation counts and PDF links |\n| `patents` | filings with ISO 8601 dates |\n| `autocomplete` | query suggestions |\n\n```js\nmicrolink.search('open source llm', { type: 'news', period: 'week' }).then(({ results }) =\u003e {\n  console.log(results[0])\n  // → { title: 'DeepSeek open sources DSpark...', publisher: 'VentureBeat', date: '2026-06-30T...' }\n})\n\nmicrolink.search('macbook pro', { type: 'shopping' }).then(({ results }) =\u003e {\n  console.log(results[0].price) // → { symbol: '$', amount: 1999 }\n})\n\nmicrolink.search('how to fine tune', { type: 'autocomplete' }).then(({ results }) =\u003e {\n  console.log(results.map(r =\u003e r.value)) // → ['how to fine tune llm', ...]\n})\n```\n\n`location` (ISO 3166-1 country code) localizes ranking and language; `period` (`hour`/`day`/`week`/`month`/`year`) constrains freshness; `limit` caps results per page:\n\n```js\nmicrolink.search('recetas de pasta', { location: 'es', limit: 10 })\n```\n\nResults compose in depth: every result with a `url` exposes lazy `.html()` and `.markdown()` for fetching the full page content only when needed — the source-expansion pattern for RAG:\n\n```js\nmicrolink.search('site:openai.com function calling guide').then(page =\u003e\n  Promise.all(\n    page.results.slice(0, 3).map(async result =\u003e ({\n      title: result.title,\n      url: result.url,\n      markdown: await result.markdown()\n    }))\n  )\n)\n```\n\nThe page itself serializes too: `page.html()` and `page.markdown()` return the whole Google results page as HTML or Markdown — useful for feeding a SERP straight to an LLM or building your own parser on top:\n\n```js\nmicrolink.search('Lotus Elise S2').then(async page =\u003e {\n  const markdown = await page.markdown() // the SERP as Markdown\n  const html = await page.html() // the SERP as HTML\n})\n```\n\nPages chain with `.next()`:\n\n```js\nmicrolink.search('node.js frameworks').then(async page =\u003e {\n  while (page) {\n    for (const result of page.results) console.log(result.title)\n    page = await page.next()\n  }\n})\n```\n\n### run(url, code, options)\n\nRun any JavaScript remotely in a sandboxed runtime — no Lambda bundle, no browser fleet, no server ([guide](https://microlink.io/docs/guides/function)). Also exposed as `function`, matching the API parameter name. You write a plain function; the library handles serialization, compression and the API call for you. When the code doesn't reference `page`, no browser is started, making execution faster and cheaper:\n\n```js\nmicrolink.run('https://example.com', () =\u003e 40 + 2).then(({ value }) =\u003e {\n  console.log(value) // → 42\n})\n```\n\nWhen it references `page`, Microlink starts a headless browser and navigates to the URL first, handing your code the full [puppeteer `page`](https://pptr.dev/api/puppeteer.page) for clicks, waits, evaluation and navigation ([browser interaction](https://microlink.io/docs/guides/function/browser-interaction)):\n\n```js\nmicrolink.run('https://example.com', async ({ page }) =\u003e {\n  await page.waitForSelector('h1')\n  return page.$eval('h1', el =\u003e el.textContent)\n}).then(({ value }) =\u003e {\n  console.log(value) // → 'Example Domain'\n})\n```\n\nAny extra option you pass is forwarded into the function scope — the simplest way to make one function reusable across requests ([custom parameters](https://microlink.io/docs/guides/function/writing-functions)):\n\n```js\nmicrolink.run(\n  'https://example.com',\n  ({ page, selector }) =\u003e page.$eval(selector, el =\u003e el.textContent),\n  { selector: 'h1' }\n).then(({ value }) =\u003e console.log(value))\n```\n\nYou can `require()` any npm package inside the function — dependencies are detected, installed on the fly into the sandbox, and cached for subsequent runs. Pin a version with `require('cheerio@1.0.0')`:\n\n```js\nmicrolink.run('https://news.ycombinator.com', async ({ page }) =\u003e {\n  const cheerio = require('cheerio')\n  const $ = cheerio.load(await page.content())\n  return $('.titleline \u003e a').map((i, el) =\u003e $(el).text()).toArray()\n}).then(({ value }) =\u003e {\n  console.log(value) // → ['Top HN story', ...]\n})\n```\n\nThe result carries more than the return value — `console.log` calls are captured in `logging`, and `profiling` reports peak cpu/memory plus per-phase timings (`install`/`build`/`spawn`/`run`) so you can spot the bottleneck ([profiling](https://microlink.io/docs/guides/function/profiling-and-performance)):\n\n```js\nmicrolink.run('https://example.com', ({ page }) =\u003e {\n  console.log('visiting page')\n  return page.title()\n}).then(({ isFulfilled, value, logging, profiling }) =\u003e {\n  console.log(isFulfilled) // → true\n  console.log(value) // → 'Example Domain'\n  console.log(logging.log) // → [['visiting page']]\n  console.log(profiling.phases) // → { install: 0, build: 7.8, spawn: 68.5, run: 0.02, total: 73.7 }\n})\n```\n\nWhen the code throws, the promise still resolves: `isFulfilled` is `false` and `value` carries the error as `{ name, message }`. Resource limits surface the same way with plan-aware errors (`TimeoutError`, `MemoryError`, `CodeSizeError`, ...) — see [troubleshooting](https://microlink.io/docs/guides/function/troubleshooting). From the CLI, put the code in a file and pass extra scope variables as flags: `microlink function https://example.com --file ./fn.js --selector h1`.\n\n## Authenticated requests\n\nSecrets stay out of URLs: `apiKey` is sent as the `x-api-key` header, and `headers` travel as real request headers:\n\n```js\nconst microlink = require('microlink.io')({ apiKey: process.env.MICROLINK_API_KEY })\n\nmicrolink.markdown('https://x.com/some/article', {\n  headers: { 'x-api-header-cookie': 'auth_token=...' } // forwarded to the target as `cookie`\n}).then(console.log)\n```\n\n## Error handling\n\nAny API error rejects with a `MicrolinkError` carrying `code`, `statusCode` and a human-readable `description`:\n\n```js\nconst { MicrolinkError } = require('microlink.io')\n\nmicrolink.screenshot('https://example.com').catch(error =\u003e {\n  if (error instanceof MicrolinkError) console.error(error.code, error.description)\n})\n```\n\n## CLI\n\nThe package ships a `microlink` binary where every product is a subcommand:\n\n```bash\nmicrolink markdown https://example.com\nmicrolink screenshot https://example.com --fullPage\nmicrolink logo https://github.com --square\nmicrolink links https://example.com\nmicrolink search \"best coffee\" --limit 10 --location es\nmicrolink extract https://microlink.io --data '{\"image\":{\"selector\":\"meta[property=og:image]\",\"attr\":\"content\",\"type\":\"image\"}}'\nmicrolink function https://example.com --file ./fn.js\n```\n\nFlags map to the same single options bag as the library. Use `--api-key` (or the `MICROLINK_API_KEY` environment variable) for authenticated calls and repeatable `--header 'Name: value'` flags for request headers. Strings print raw to stdout; objects pretty-print as JSON.\n\n## Related\n\n- [@microlink/mql](https://github.com/microlinkhq/mql) — the low-level Microlink Query Language client (raw envelopes, `buffer`/`stream` access).\n- [@microlink/google](https://github.com/microlinkhq/google) — structured Google data, powering `search`.\n- [@microlink/function](https://github.com/microlinkhq/function) — remote JavaScript functions, powering `function`/`run` ([guides](https://microlink.io/docs/guides/function)).\n\n## License\n\n**microlink.io** © [microlink.io](https://microlink.io), released under the [MIT](https://github.com/microlinkhq/microlink/blob/master/LICENSE.md) License.\n\n\u003e [microlink.io](https://microlink.io) · GitHub [microlinkhq](https://github.com/microlinkhq) · X [@microlinkhq](https://x.com/microlinkhq)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmicrolinkhq%2Fmicrolink","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmicrolinkhq%2Fmicrolink","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmicrolinkhq%2Fmicrolink/lists"}