{"id":13517554,"url":"https://github.com/krakenjs/kraken-js","last_synced_at":"2025-05-14T22:06:24.443Z","repository":{"id":45964927,"uuid":"13224032","full_name":"krakenjs/kraken-js","owner":"krakenjs","description":"An express-based Node.js web application bootstrapping module.","archived":false,"fork":false,"pushed_at":"2025-01-31T15:27:11.000Z","size":734,"stargazers_count":4932,"open_issues_count":0,"forks_count":460,"subscribers_count":212,"default_branch":"v2.x","last_synced_at":"2025-05-07T21:58:19.014Z","etag":null,"topics":["expressjs","javascript","krakenjs","middleware"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/krakenjs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-09-30T18:54:00.000Z","updated_at":"2025-05-04T23:01:15.000Z","dependencies_parsed_at":"2024-06-18T12:26:10.896Z","dependency_job_id":"d37c8e05-f8fb-4fd2-9f49-5681f7122554","html_url":"https://github.com/krakenjs/kraken-js","commit_stats":{"total_commits":387,"total_committers":52,"mean_commits":"7.4423076923076925","dds":0.6976744186046512,"last_synced_commit":"0ec17f8b84c497d597ff4149454f60a30a3d5584"},"previous_names":[],"tags_count":25,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krakenjs%2Fkraken-js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krakenjs%2Fkraken-js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krakenjs%2Fkraken-js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krakenjs%2Fkraken-js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/krakenjs","download_url":"https://codeload.github.com/krakenjs/kraken-js/tar.gz/refs/heads/v2.x","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253194932,"owners_count":21869338,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["expressjs","javascript","krakenjs","middleware"],"created_at":"2024-08-01T05:01:35.008Z","updated_at":"2025-05-14T22:06:24.378Z","avatar_url":"https://github.com/krakenjs.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","⚙️ Backend \u0026 APIs"],"sub_categories":[],"readme":"\u003e [!CAUTION]\n\u003e The kraken-js repo is not actively monitored or accepting new features. It is recommended not to use this for new products and migrate away for existing ones.\n\n![kraken-js](public/krakenLogo.png)\n\n# kraken.js\n\n[![Build Status](https://travis-ci.org/krakenjs/kraken-js.svg?branch=v1.0.x)](https://travis-ci.org/krakenjs/kraken-js) [![Greenkeeper badge](https://badges.greenkeeper.io/krakenjs/kraken-js.svg)](https://greenkeeper.io/)  \n\nKraken builds upon [express](http://expressjs.com/) and enables environment-aware, dynamic configuration, advanced middleware capabilities, security, and app lifecycle events.\nFor more information and examples check out [krakenjs.com](http://krakenjs.com)\n\nTable of Contents\n=================\n\n* [Basic Usage](#basic-usage)\n* [API](#api)\n  * [Options](#options)\n* [Config Protocols](#config-protocols)\n* [Features](#features)\n  * [Configuration](#configuration)\n    * [Environment-aware](#environment-aware)\n  * [Middleware](#middleware)\n    * [Included Middleware](#included-middleware)\n    * [Extending Default Middleware](#extending-default-middleware)\n  * [Application Security](#application-security)\n  * [Lifecycle Events](#lifecycle-events)\n  * [Configuration-based express Settings](#configuration-based-express-settings)\n  * [View Engine Configuration](#view-engine-configuration)\n* [Tests](#tests)\n* [Coverage](#coverage)\n* [Reading app configs from within the kraken app](#reading-app-configs-from-within-the-kraken-app)\n\n## Basic Usage\n\n```javascript\n'use strict';\n\nvar express = require('express'),\n    kraken = require('kraken-js');\n\nvar app = express();\napp.use(kraken());\napp.listen(8000);\n```\n\n\n## API\n\n`kraken([options])`\n\nkraken-js is used just like any normal middleware, however it does more than just return a function; it configures a\ncomplete express 4 application. See below for a list of features, but to get started just use it like middleware.\n\n```javascript\napp.use(kraken());\n// or to specify a mountpath for your application:\n// app.use('/mypath', kraken());\n\n// Note: mountpaths can also be configured using the\n// `express:mountpath` config setting, but that setting\n// will be overridden if specified in code.\n```\n\n### Options\nPass the following options to kraken via a config object such as this:\n\n```javascript\nvar options = {\n    onconfig: function (config, callback) {\n        // do stuff\n        callback(null, config);\n    }\n};\n\n// ...\n\napp.use(kraken(options));\n```\nNote: All kraken-js configuration settings are optional.\n\n#### `basedir` (*String*, optional)\nThe working directory for kraken to use. kraken loads configuration files,\nroutes, and registers middleware so this directory is the path against all relative paths are resolved. The default value\nis the directory of the file that uses kraken, which is generally `index.js` (or `server.js`).\n\n#### `onconfig` (*Function*, optional)\nProvides an asynchronous hook for loading additional configuration. When invoked, a\n[confit](https://github.com/krakenjs/confit) configuration object containing all loaded configuration value passed\nas the first argument, and a callback as the second. The signature of this handler is `function (config, callback)`\nand the callback is a standard error-back which accepts an error as the first argument and the config object as the\nsecond, e.g. `callback(null, config)`.\n\n#### `protocols` (*Object*, optional)\nProtocol handler implementations for use when processing configuration. For more information on protocols\nsee [shortstop](https://github.com/krakenjs/shortstop) and [shortstop-handlers](https://github.com/krakenjs/shortstop-handlers).\nBy default, kraken comes with a set of shortstop protocols which are described in the \"Config Protocols\" section below,\nbut you can add your own by providing an object with the protocol names as the keys and their implementations as\nproperties, for example:\n```javascript\nvar options = {\n    protocols: {\n        file: function file(value, callback) {\n            fs.readFile(value, 'utf8', callback);\n        }\n    }\n};\n```\n\n#### `onKrakenMount` (*Function*, optional)\nProvides a synchronous hook which executes once kraken mounts. It takes an express `app` instance as the first argument, and `options` as the second. The signature of this handler is `function (app, options)`.\n\n#### `uncaughtException` (*Function*, optional)\nHandler for `uncaughtException` errors outside of the middleware chain. See the [endgame](https://github.com/krakenjs/endgame) module for defaults.\n\nFor uncaught errors in the middleware chain, see `shutdown` middleware instead.\n\n#### `confit` (*Object*, optional)\nIn rare cases, it may be useful to pass options directly to the confit module used within [lib/config.js](lib/config.js#71).\nFor example, if [confit/shortstop is conflicting with environment variables](https://github.com/krakenjs/kraken-js/issues/470), you can explicitly ignore those environment variables:\n```javascript\nvar options = {\n    confit: {\n        envignore: ['troublesome_environment_variable']\n    }\n};\n```\n\n## Config Protocols\nkraken comes with the following shortstop protocol handlers by default:\n#### `import:`\nMerge the contents of the specified file into configuration under a given key.\n```json\n{\n    \"foo\": \"import:./myjsonfile\"\n}\n```\n\n#### `config:`\nReplace with the value at a given key. Note that the keys in this case are dot (.) delimited.\n```json\n{\n    \"foo\": {\n        \"bar\": true\n    },\n    \"foobar\": \"config:foo.bar\"\n}\n```\n\n#### `path:`\nThe path handler is documented in the [shortstop-handlers](https://github.com/krakenjs/shortstop-handlers#handlerspathbasedir) repo.\n\n#### `file:`\nThe file handler is documented in the [shortstop-handlers](https://github.com/krakenjs/shortstop-handlers#handlersfilebasedir-options) repo.\n\n#### `base64:`\nThe base64 handler is documented in the [shortstop-handlers](https://github.com/krakenjs/shortstop-handlers#handlersbase64) repo.\n\n#### `env:`\nThe env handler is documented in the [shortstop-handlers](https://github.com/krakenjs/shortstop-handlers#handlersenv) repo.\n\n#### `require:`\nThe require handler is documented in the [shortstop-handlers](https://github.com/krakenjs/shortstop-handlers#handlersrequirebasedir) repo.\n\n#### `exec:`\nThe exec handler is documented in the [shortstop-handlers](https://github.com/krakenjs/shortstop-handlers#handlersexecbasedir) repo.\n\n#### `glob:`\nThe glob handler is documented in the [shortstop-handlers](https://github.com/krakenjs/shortstop-handlers#handlersglobbasediroptions) repo.\n\n#### `resolve:`\nThe resolve handler is documented in the [shortstop-resolve](https://github.com/jasisk/shortstop-resolve) repo.\n\n\n\n\n## Features\n\n\n### Configuration\n\n\n#### Environment-aware\n\nUsing environment suffixes, configuration files are applied and overridden according to the current environment as set\nby `NODE_ENV`. The application looks for a `./config` directory relative to the basedir and looks for `config.json` as the baseline config specification. JSON files matching the current env are processed and loaded. Additionally, JSON configuration files may contain comments.\n\nValid `NODE_ENV` values are `undefined` or `dev[elopment]` (uses `development.json`), `test[ing]` (uses `test.json`), `stag[e|ing]` (uses `staging.json`), `prod[uction]` (uses `config.json`). Simply add a config file with the name, to have it read only in that environment, e.g. `config/development.json`.\n\n\n### Middleware\n\nMuch like configuration, you shouldn't need to write a lot of code to determine what's in your middleware chain. [meddleware](https://github.com/paypal/meddleware) is used internally to read,\nresolve, and register middleware with your express application. You can either specify the middleware in your `config.json` or `{environment}.json`, (or) import it from a separate json file using the import protocol mentioned above.\n\n#### Included Middleware\nKraken comes with common middleware already included in its `config.json` file. The following is a list of the included middleware and their default configurations which can be overridden in your app's configuration:\n* `\"shutdown\"` - internal middleware which handles graceful shutdowns in production environments\n  - Priority - 0\n  - Enabled - `true` if *not* in a development environment\n  - Module - `\"kraken-js/middleware/shutdown\"`\n    - Arguments (*Array*)\n      - *Object*\n        - `\"timeout\"` - milliseconds (default: `30000`)\n        - `\"template\"` - template to render (default: `null`)\n        - `\"shutdownHeaders\"` - custom headers to write while still disconnecting.\n        - `\"uncaughtException\"` - custom handler - `function (error, req, res, next)` - for uncaught errors. Default behavior is to log the error and then trigger shutdown.\n* `\"compress\"` - adds compression to server responses\n  - Priority - 10\n  - Enabled - `false` (disabled in all environments by default)\n  - Module - `\"compression\"` ([npm](https://www.npmjs.org/package/compression))\n* `\"favicon\"` - serves the site's favicon\n  - Priority - 30\n  - Module - `\"serve-favicon\"` ([npm](https://www.npmjs.org/package/serve-favicon))\n    - Arguments (*Array*)\n      - *String* - local path to the favicon file (default: `\"path:./public/favicon.ico\"`)\n* `\"static\"` - serves static files from a specific folder\n  - Priority - 40\n  - Module - `\"serve-static\"` ([npm](https://www.npmjs.org/package/serve-static))\n    - Arguments (*Array*)\n      - *String* - local path to serve static files from (default: `\"path:./public\"`)\n* `\"logger\"` - logs requests and responses\n  - Priority - 50\n  - Module - `\"morgan\"` ([npm](https://www.npmjs.org/package/morgan))\n    - Arguments (*Array*)\n      - *String* - log format type (default: `\"combined\"`)\n* `\"json\"` - parses JSON request bodies\n  - Priority - 60\n  - Module - `\"body-parser\"` ([npm](https://www.npmjs.org/package/body-parser))\n    - Method - `\"json\"`\n* `\"urlencoded\"` - parses URL Encoded request bodies\n  - Priority - 70\n  - Module - `\"body-parser\"` ([npm](https://www.npmjs.org/package/body-parser))\n    - Method - `\"urlencoded\"`\n    - Arguments (*Array*)\n      - *Object*\n        - `\"extended\"` (*Boolean*) - parse extended syntax with the [qs](https://www.npmjs.org/package/qs) module (default: `true`)\n* `\"multipart\"` - parses multipart FORM bodies\n  - Priority - 80\n  - Module - `\"kraken-js/middleware/multipart\"` (delegates to [formidable](https://www.npmjs.org/package/formidable))\n* `\"cookieParser\"` - parses cookies in request headers\n  - Priority - 90\n  - Module - `\"cookie-parser\"` ([npm](https://www.npmjs.org/package/cookie-parser))\n    - Arguments (*Array*)\n      - *String* - secret used to sign cookies (default: `\"keyboard cat\"`)\n* `\"session\"` - maintains session state\n  - Priority - 100\n  - Module - `\"express-session\"` ([npm](https://www.npmjs.org/package/express-session))\n    - Arguments (*Array*)\n      - *Object*\n        - `\"key\"` (*String*) - cookie name (default: `\"connect.sid\"`)\n        - `\"secret\"` (*String*) - secret used to sign session cookie (default: `\"keyboard cat\"`)\n        - `\"cookie\"` (*Object*) - describing options for the session cookie\n          - `\"path\"` (*String*) - base path to verify cookie (default: `\"/\"`)\n          - `\"httpOnly\"` (*Boolean*) - value indicating inaccessibility of cookie in the browser (default: `true`)\n          - `\"maxAge\"` (*Number*) - expiration of the session cookie (default: `null`)\n        - `\"resave\"` (*Boolean*) - value indicating whether sessions should be saved even if unmodified (default: `true`)\n        - `\"saveUninitialized\"` (*Boolean*) - value indicating whether to save uninitialized sessions (default: `true`)\n        - `\"proxy\"` (*Boolean*) - value indicating whether to trust the reverse proxy (default: `null`, inherit from `express`)\n* `\"appsec\"` - secures the application against common vulnerabilities (see Application Security below)\n  - Priority - 110\n  - Module - `\"lusca\"` ([github](https://github.com/paypal/lusca))\n    - Arguments (*Array*)\n      - *Object*\n        - `\"csrf\"` (*Boolean*|*Object*) - value indicating whether to require CSRF tokens for non GET, HEAD, or OPTIONS requests, or an options object to configure CSRF protection (default: `true`)\n        - `\"xframe\"` (*String*) - value for the `X-Frame-Options` header (default: `\"SAMEORIGIN\"`)\n        - `\"p3p\"` (*String*|*Boolean*) - the Compact Privacy Policy value or `false` if not used (default: `false`)\n        - `\"csp\"` (*Object*|*Boolean*) - options configuring Content Security Policy headers or `false` if not used (default: `false`)\n* `\"router\"` - routes traffic to the applicable controller\n  - Priority - 120\n  - Module - `\"express-enrouten\"` ([npm](https://www.npmjs.org/package/express-enrouten))\n    - Arguments (*Array*)\n      - *Object*\n        - `\"index\"` (*String*) - path to the single file to load (default: `\"path:./routes\"`)\n\nAdditional notes:\n- The session middleware defaults to using the in-memory store. This is **not** recommended for production applications and the configuration should be updated to use a shared resource (such as Redis or Memcached) for session storage.\n- You can change the routes which are affected by the middleware by providing a top-level option of `route`. In express deployments, it is common to re-route where static files are served which can be accomplished like so:\n\n```json\n// include this in your own config.json and this will merge with the Kraken defaults\n// NB: if you use kraken-devtools you must re-route that as well in development.json!\n{\n    \"static\": {\n        \"route\": \"/static\"\n    }\n}\n```\n\n#### Extending Default Middleware\nIn any non-trivial Kraken deployment you will likely need to extend the included middleware. Common middleware which need extension include cookie parsing and session handling. In those particular cases, the secrets used should be updated:\n\n```js\n{\n    // include this in your own config.json and this will merge with the Kraken defaults\n    \"middleware\": {\n\n        \"cookieParser\": {\n            \"module\": {\n                \"arguments\": [ \"your better secret value\" ]\n            }\n        },\n\n        \"session\": {\n            \"module\": {\n                // NB: arrays like 'arguments' are not merged but rather replaced, so you must\n                //     include all required configuration options here.\n                \"arguments\": [\n                    {\n                        \"secret\": \"a much better secret\",\n                        \"cookie\": {\n                            \"path\": \"/\",\n                            \"httpOnly\": true,\n                            \"maxAge\": null\n                        },\n                        \"resave\": true,\n                        \"saveUninitialized\": true,\n                        \"proxy\": null\n                    }\n                ]\n            }\n        }\n\n    }\n}\n```\n\nAnother common update is to pass options to middleware which is configured only with the defaults, such as the compression middleware:\n\n```js\n{\n    \"middleware\": {\n        \"compress\": {\n            \"enabled\": true,    // response compression is disabled by default\n            \"module\": {\n                \"arguments\": [\n                    {\n                        // 512 byte minimum before compressing output\n                        \"threshold\": 512\n                    }\n                ]\n            }\n        }\n    }\n}\n```\n\nMore complicated examples include configuring the session middleware to use a shared resource, such as [connect-redis](https://www.npmjs.org/package/connect-redis). This requires a few extra steps, most notably creating your own middleware to handle the registration (see [totherik/redis-example](https://github.com/totherik/redis-example) for a complete example):\n\n  1. Overlay the existing session middleware in your configuration:\n\n  ```js\n  {\n      // in your config.json\n      \"middleware\": {\n          \"session\": {\n              \"module\": {\n                  // use your own module instead\n                  \"name\": \"path:./lib/middleware/redis-session\",\n                  \"arguments\": [\n                      // express-session configuration\n                      {\n                          \"secret\": \"a much better secret\",\n                          \"cookie\": {\n                              \"path\": \"/\",\n                              \"httpOnly\": true,\n                              \"maxAge\": null\n                          },\n                          \"resave\": true,\n                          \"saveUninitialized\": true,\n                          \"store\": null    // NB: this will be overlaid in our module\n                      },\n                      // connect-redis configuration\n                      {\n                          \"host\": \"localhost\",\n                          \"port\": 6379,\n                          \"prefix\": \"session:\"\n                      }\n                  ]\n              }\n          }\n      }\n  }\n  ```\n\n  2. Add your custom middleware for Kraken to configure:\n\n  ```javascript\n  // ./lib/middleware/redis-session.js\n  'use strict';\n\n  var session = require('express-session'),\n      RedisStore = require('connect-redis')(session);\n\n  /** Creates a REDIS-backed session store.\n   *\n   * @param {Object} [sessionConfig] Configuration options for express-session\n   * @param {Object} [redisConfig] Configuration options for connect-redis\n   * @returns {Object} Returns a session middleware which is backed by REDIS\n   */\n  module.exports = function (sessionConfig, redisConfig) {\n\n      // add the 'store' property to our session configuration\n      sessionConfig.store = new RedisStore(redisConfig);\n\n      // create the actual middleware\n      return session(sessionConfig);\n  };\n  ```\n\n\n### Application Security\n\nKraken uses [lusca](https://github.com/paypal/lusca) to secure your applications, so that you don't need to think about it. Techniques like CSRF, XFRAMES, and CSP are enabled automatically while others can be opted into. All are customizable through configuration.\n\n\n### Lifecycle Events\n\nKraken adds support for additional events to your express app instance:\n\n* `start` - the application has safely started and is ready to accept requests\n* `shutdown` - the application is shutting down, no longer accepting requests\n* `stop` - the http server is no longer connected or the shutdown timeout has expired\n\n\n\n### Configuration-based `express` Settings\nSince express instances are themselves config objects, the convention is to set values on the app instance for use by\nexpress internally as well as other code across the application. kraken-js allows you to configure express via JSON.\nAny properties are supported, but kraken-js defaults include:\n```js\n{\n    \"express\": {\n        \"env\": \"\", // NOTE: `env` is managed by the framework. This value will be overwritten.\n        \"x-powered-by\": false,\n        \"trust proxy\": false,\n        \"jsonp callback name\": null,\n        \"json replacer\": null,\n        \"json spaces\": 0,\n        \"case sensitive routing\": false,\n        \"strict routing\": false,\n        \"view cache\": true,\n        \"view engine\": null,\n        \"views\": \"path:./views\",\n        \"route\": \"/\"\n    }\n}\n```\n\nAdditional notes:\n- The `env` setting will be set to the environment value as derived by kraken-js, so what is put here will be overwritten\nat runtime.\n- Set the `view engine` property to the one of the `view engines` property names (see the section `View Engine Configuration`)\nto enable it for template rendering.\n- The optional `view` property is a special case in which you can set a path to a module which exports a constructor implementing\nthe view API as defined by the module `express/lib/view`. If set, kraken-js will attempt to load the specified module and\nconfigure express to use it for resolving views.\n\nFor example:\n\n```js\n{\n    \"express\": {\n        \"view\": \"path:./lib/MyCustomViewResolver\"\n    }\n}\n```\n\n\n### View Engine Configuration\nkraken-js looks to the `view engines` config property to understand how to load and initialize renderers. The value of the\n`view engines` property is an object mapping the desired file extension to engine config settings. For example:\n```js\n{\n    \"view engines\": {\n        \"jade\": {\n            \"module\": \"consolidate\"\n        },\n        \"html\": {\n            \"name\": \"ejs\",\n            \"module\": \"ejs\",\n            \"renderer\": \"renderFile\"\n        },\n        \"dust\": {\n            \"module\": \"adaro\",\n            \"renderer\": {\n                \"method\": \"dust\",\n                \"arguments\": [{\n                    \"cache\": false,\n                    \"helpers\": [\"dust-helpers-whatevermodule\"]\n                }]\n            }\n        },\n        \"js\": {\n            \"module\": \"adaro\",\n            \"renderer\": {\n                \"method\": \"js\",\n                \"arguments\": [{ \"cache\": false }]\n            }\n        }\n    }\n}\n```\n\nThe available engine configuration options are:\n\n- `module` (*String*) - This is the node module that provides the renderer implementation. The value can be the name of a\nmodule installed via npm, or it can be a module in your project referred to via file path, for example `\"module\": \"path:./lib/renderer\"`.\n- `name` (*String*, optional) - Set this if the name of the rendering engine is different from the desired file extension.\nFor example, you chose to use ejs, but want to use the \"html\" file extension for your templates. Additionally, if the\nrenderer function exported by the module is not the file extension and a \"renderer\" property is not defined, this value will be used.\n- `renderer` (*String|Object*, optional) - The renderer property allows you to explicitly identify the property or the\nfactory method exported by the module that should be used when settings the renderer. Set the value to a String to identify\nthat the renderer is exported by that name, or an object with the properties \"method\" and \"arguments\" to identify a factory method.\nFor example, using ejs you could set this property to \"renderFile\" or \"__express\" as the ejs module exports a renderer directly.\n\n## Tests\n```bash\n$ npm test\n```\n\n## Coverage\n```bash\n$ npm run-script cover \u0026\u0026 open coverage/lcov-report/index.html\n```\n\n## Reading app configs from within the kraken app\n\nThere are two different ways. You can\n\n* Read it in your `onconfig` handler as mentioned above.\n```\nfunction (config, callback) {\n    var value = config.get('\u003ckey\u003e');\n    ...\n    ...\n    callback(null, config);\n}\n```\n* Read it off the `req` object by doing `req.app.kraken.get('\u003cconfig-key\u003e')`. So it would look like:\n```\nrouter.get('/', function (req, res) {\n    var value = req.app.kraken.get('\u003ckey\u003e');\n    ...\n    ...\n});\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkrakenjs%2Fkraken-js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkrakenjs%2Fkraken-js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkrakenjs%2Fkraken-js/lists"}