Writing DuckDuckGo plugins just got easier

The developers behind DuckDuckGo, the search engine that doesn’t track you, have made it easier than ever to write plugins for the site. With the first global Quack & Hack event taking place later this month, there’s never been a better time to get involved.

Instant Answers

The DuckDuckGo engine supports several types of plugin, but instant answers that provide a static “cheatsheet” are a simple to get started. Previously developing a new instant answer would require a Perl module, a test file and a plain text version of the response. Now all you need to provide is a JSON file of your instant answer and you’re in business.


You’ll need to fork the DuckDuckGo repo and clone your forked repo to your development machine. Optionally you can install App::DuckPAN, which can launch a local version of the DuckDuckGo site for testing your code. Another way to test the cheatsheet is via Codio.

An Instant Answer JSON file

Instant answer JSON files should be created in the share/goodie/cheat_sheets directory in the repo. A good way to start is to copy one of the existing files and change it to include your content.

This is a truncated example from my perldoc instant answer:

    "id": "perldoc_cheat_sheet",
    "name": "perldoc",
    "description": "Perl Documentation",
    "metadata": {
        "sourceName": "perldoc Manual",
        "sourceUrl": "http://perldoc.perl.org/perldoc.html"
    "section_order": ["Usage", "Module Options", "Search Options", "Common Options"],
    "sections": {
        "Usage": [
            "key": "[perldoc <option>]",
            "val": "start perldoc"
            "key": "[perldoc perldoc]",
            "val": "perldoc help"

The id and name fields should be unique values that describe the plugin. The metadata fields describe the source of the information in the instant answer. It’s good to use a canonical source - in this case I referenced the official Perl documentation.

The sections field is the content of the instant answer. Each entry is a key value for an array of key pairs. section_order describes the order in which the sections will be displayed in the search engine results, so make sure you put the most important sections first!

Let’s take a closer look at a section entry, here is Module Options:

        "Module Options": [
            "key": "Module::Name",
            "val": "Show module documentation"
            "key": "[-l Module::Name]",
            "val": "Module filepath"
            "key": "[-m Module::Name]",
            "val": "Module source code"
            "key": "[-lm Module::Name]",
            "val": "Module filepath (alt.)"

“Module Options” is the section name, this must be present exactly in the section_order field, or this section will not appear at all. The section name text is the subheading used for the section, so be sure to choose something readable: “Module Options” is better than “module_options”.

Each key pair entry represents the text to be displayed for the instant answer, the key text should be the code and val the description. If the key text contains spaces, wrap the text in square brackets to ensure it’s displayed as code on the web page (see this article’s cover image for examples). You can find the complete perldoc JSON file here.

Wrap up

You can test your instant answer using App::DuckPAN (see my previous article for examples). If you want to discuss your instant answer with a developer, or resolve an issue, the DuckDuckGo team are on Slack, you can request access via email. The official documentation is also useful.

Once you’ve finished an instant answer, create a pull request! The DuckDuckGo developers will review your code and give feedback. Once your instant answer is approved, it will go live within a few days.

Updated: Changed chat details for DDG slack 2015-08-26

This article was originally posted on PerlTricks.com.


David Farrell

David is a professional programmer who regularly tweets and blogs about code and the art of programming.

Browse their articles


Something wrong with this article? Help us out by opening an issue or pull request on GitHub