> ## Documentation Index > Fetch the complete documentation index at: https://bunny.net/docs/llms.txt > Use this file to discover all available pages before exploring further. # Introduction > The Scriptable DNS allows you to dynamically respond to DNS queries using JavaScript scripts. The following pages contain sample documentation to help you get started. ## Quickstart Create a DNS script, test it, publish it, and attach it to a hostname in your zone. > [tab] Dashboard > > **1. Create a DNS Script** > > In the bunny.net dashboard, go to [**DNS Scripts**](https://dash.bunny.net/dns/scripts) and click **Add DNS Script**. > > **2. Write your script** > > The Code editor opens with a starter script that answers every query with a TXT record: > > ```javascript theme={null} > /* > Handle the DNS query! > */ > export default function handleQuery(event) { > return new TxtRecord("Hello world!"); > } > ``` > > Edit the script to return the response you need, such as an `ARecord` for IP-based routing. See the [entry function](#entry-function) below for the query details available to your script. > > **3. Test it** > > Use the fields below the editor to simulate a query: set the **Type**, **Hostname**, **Client IP**, **EDNS IP**, and **Location**, then click **Run**. > > The **Response** panel shows the DNS response your script returned, so you can try different request parameters and evaluate how your script behaves. Output from `console.log` appears in the **Console** tab. > > **4. Publish the script** > > Click **Save** to store your changes, then **Publish** to make the script live. > > **5. Attach it to a DNS Zone** > > A script only answers queries once a record points at it: > > 1. Go to **DNS** and select your DNS Zone > 2. Click **Add DNS Record** > 3. Enter a **Hostname** > 4. Select **SCR** as the **Type** > 5. Select the script you just published in the **Script** dropdown > 6. Click **Add Record** > > Queries for that hostname are now answered by your script. > [tab] CLI > > > [!NOTE] > > > > Don't have the CLI installed? See the [CLI quickstart](https://bunny.net/docs/cli/quickstart.md) to install and authenticate. > > **1. Scaffold a project** > > ```bash theme={null} > bunny dns scripts init hello-dns > ``` > > This writes a `handleQuery` entry file, a `tsconfig.json`, and a `package.json` with the [type definitions](#type-safety) preconfigured, and links the directory to the script. Pass `--example` to start from a template (`empty`, `geo`, `closest`, `weighted`, `failover`, `pullzone`). > > **2. Write your script** > > Edit the entry file to return the response you need. See the [entry function](#entry-function) below for the query details available to your script. > > **3. Deploy the script** > > Upload and publish the linked script's entry file: > > ```bash theme={null} > bunny dns scripts deploy > ``` > > **4. Attach it to a DNS Zone** > > A script only answers queries once a record points at it. Add a `SCRIPT` record to a zone: > > ```bash theme={null} > bunny dns scripts attach example.com api > ``` > > The command confirms before writing the record. Verify it by querying the record type your script answers: > > ```bash theme={null} > dig api.example.com A > ``` > > See the [`bunny dns` command reference](https://bunny.net/docs/cli/commands/dns) for the full list of script commands. ## Entry function The Scriptable DNS pipeline executes through a statically defined function **handleQuery**. To return a response to the query, you can return one of the DNS response objects as documented in the [Query Response Object Types](https://bunny.net/docs/dns/scriptable/query-response-object-types.md). ```javascript theme={null} export default function handleQuery(query) { return new ARecord("111.111.111.111", 30); } ``` > [!WARNING] > > `console.log` is intended for use within the Script Editor only. Please remove > all logging statements before saving or publishing, as they may cause your > script to fail at runtime. ## Query object The entry function is passed a DnsRequest object parameter called **query** that contains the information about the request, such as the hostname, country, remote IP, etc. ### DnsRequest | Field | Type | Description | | - | - | - | | `request` | DnsQuery | The DNS query request that contains the details about the query | ### DnsQuery | Field | Type | Description | | - | - | - | | `hostname` | string | The hostname that is being queried | | `clientIP` | string | The IP of the remote client that sent the DNS query | | `queryType` | string | The query question type (A, AAAA, TXT) | | `ednsIP` | string | The EDNS0 IP of the DNS query that was attached by the client | | `geoLocation` | GeoLocation | The geo location of the client | | `serverZone` | string | The server zone of the DNS server that received the query (DE, UK, SG, etc.) | ### GeoLocation | Field | Type | Description | | - | - | - | | `latitude` | double | The latitude location of the client | | `longitude` | double | The longitude location of the client | | `country` | string | The detected two letter ISO country code of the client | | `asn` | long | The detected ASN number of the client | ## Type safety The Scriptable DNS runtime injects its globals (such as `ARecord` and the other [response object types](https://bunny.net/docs/dns/scriptable/query-response-object-types.md)) directly into your script, and does not support `import`. The [`@bunny.net/scriptable-dns-types`](https://github.com/BunnyWay/cli/tree/main/packages/scriptable-dns-types) package provides ambient TypeScript declarations for these globals, giving you editor autocomplete and optional type checking without any runtime imports. Install it as a development dependency: ```bash theme={null} npm install --save-dev @bunny.net/scriptable-dns-types ``` Then reference the types from within your script file with a triple-slash directive: ```javascript theme={null} /// /** @param {DnsRequest} query */ export default function handleQuery(query) { if (query.request.geoLocation.country === "DE") { return new ARecord("203.0.113.20", 30); } return new ARecord("203.0.113.10", 30); } ``` Or enable them project-wide through `tsconfig.json`: ```json theme={null} { "compilerOptions": { "allowJs": true, "checkJs": true, "noEmit": true, "types": ["@bunny.net/scriptable-dns-types"] } } ``` This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.