This repository was archived by the owner on Jun 8, 2026. It is now read-only.

Repository files navigation

The Bash Builder takes an entrypoint of a Bash function, imports its dependencies, and bundles them into a serverless function.

A simple "hello world" example:

handler() {
echo"Hello, from $(bash --version | head -n1)"
}

Demo:https://vercel.import.sh/api/hello

Usage

This example will detail creating an uppercase endpoint which will be accessed as https://my-deployment.url/api/uppercase. This endpoint will convert the provided querystring to uppercase using only Bash functions and standard Unix CLI tools.

Start by creating the project structure:

mkdir -p my-bash-project/api/uppercase
cd my-bash-project/api/uppercase

Inside the my-bash-project/api/uppercase directory, create an index.sh file with the following contents:

import "string@0.0.1"
import "querystring@1.3.0"handler() {
local path
path="$(jq -r '.path'<"$1")"
querystring "$path"| querystring_unescape | string_upper
}

The final step is to define a build that will take this entrypoint (index.sh), build it, and turn it into a serverless function using a vercel.json configuration in the root directory (my-bash-project):

{
"version": 2,
"functions": {
"api/*.sh": { "runtime": "vercel-bash@4.2.0" }
}
}

Import can be configured by adding options to the import property of the config. The IMPORT_ prefix must not be set in this case:

{
"version": 2,
"functions": {
"api/*.sh": {
"runtime": "vercel-bash@4.1.0",
"config": {
"import": {
"DEBUG": "1"
}
}
}
}
}

By passing in a querystring, the endpoint will return the uppercased version.

Demo:https://vercel.import.sh/api/uppercase?hello%20world

Build Logic

If your serverless function requires additional files to be added into the final bundle, an optional build() function may be defined.

Any files added to the current working directory at build-time will be included in the output serverless function.

build() {
date > build-time.txt
}
handler() {
echo"Build time: $(cat build-time.txt)"echo"Current time: $(date)"
}

Demo:https://vercel.import.sh/api/build

Response Headers

The default Content-Type is text/plain; charset=utf8 but you can change it by setting a response header.

handler() {
http_response_header "Content-Type""text/html; charset=utf8"echo"<h1>Current time</h1><p>$(date)</p>"
}

Demo:https://vercel.import.sh/api/response-headers

JSON Response

It is common for serverless functions to communicate via JSON, so you can use the http_response_json function to set the Content-Type to application/json; charset=utf8.

handler() {
http_response_json
echo"{ \"title\": \"Current time\", \"body\": \"$(date)\" }"
}

Demo:https://vercel.import.sh/api/response-json

Status Code

The default status code is 200 but you can change it with the http_response_code function.

handler() {
http_response_code 500
echo"Internal Server Error from Bash!"
}

Demo:https://vercel.import.sh/api/response-status-code

Redirect

You can use the http_response_redirect function to set the location and, optionally, the status code. The default status code is 302 (temporary redirect) but you could use a permanent redirect by setting the second argument to 301.

handler() {
http_response_redirect "https://twitter.com/vercel" 301
echo"Redirecting..."
}

Demo:https://vercel.import.sh/api/redirect

Importing Dependencies

Bash, by itself, is not very useful for writing serverless function handler logic because it does not have a standard library. For this reason, import is installed and configured by default, which allows your script to easily include additional functionality and helper logic.

For example, the querystring import may be used to parse input parameters from the request URL:

import "querystring@1.3.0"handler() {
local path
local query
path="$(jq -r '.path'<"$1")"
query="$(querystring "$path")"echo"Querystring is: $query"
}

Demo:https://vercel.import.sh/api/querystring?a=b

Bash Version

With the Bash Builder, the handler script is executed using GNU Bash 4.

handler() {
bash --version
}

Demo:https://vercel.import.sh/api/bash-version

About

🐚 Bash Runtime for β–² Vercel serverless functions

Resources

Stars

94 stars

Watchers

5 watching

Forks

Releases

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
This repository was archived by the owner on Jun 8, 2026. It is now read-only.

Repository files navigation

The Bash Builder takes an entrypoint of a Bash function, imports its dependencies, and bundles them into a serverless function.

A simple "hello world" example:

handler() {
echo"Hello, from $(bash --version | head -n1)"
}

Demo:https://vercel.import.sh/api/hello

Usage

This example will detail creating an uppercase endpoint which will be accessed as https://my-deployment.url/api/uppercase. This endpoint will convert the provided querystring to uppercase using only Bash functions and standard Unix CLI tools.

Start by creating the project structure:

mkdir -p my-bash-project/api/uppercase
cd my-bash-project/api/uppercase

Inside the my-bash-project/api/uppercase directory, create an index.sh file with the following contents:

import "string@0.0.1"
import "querystring@1.3.0"handler() {
local path
path="$(jq -r '.path'<"$1")"
querystring "$path"| querystring_unescape | string_upper
}

The final step is to define a build that will take this entrypoint (index.sh), build it, and turn it into a serverless function using a vercel.json configuration in the root directory (my-bash-project):

{
"version": 2,
"functions": {
"api/*.sh": { "runtime": "vercel-bash@4.2.0" }
}
}

Import can be configured by adding options to the import property of the config. The IMPORT_ prefix must not be set in this case:

{
"version": 2,
"functions": {
"api/*.sh": {
"runtime": "vercel-bash@4.1.0",
"config": {
"import": {
"DEBUG": "1"
}
}
}
}
}

By passing in a querystring, the endpoint will return the uppercased version.

Demo:https://vercel.import.sh/api/uppercase?hello%20world

Build Logic

If your serverless function requires additional files to be added into the final bundle, an optional build() function may be defined.

Any files added to the current working directory at build-time will be included in the output serverless function.

build() {
date > build-time.txt
}
handler() {
echo"Build time: $(cat build-time.txt)"echo"Current time: $(date)"
}

Demo:https://vercel.import.sh/api/build

Response Headers

The default Content-Type is text/plain; charset=utf8 but you can change it by setting a response header.

handler() {
http_response_header "Content-Type""text/html; charset=utf8"echo"<h1>Current time</h1><p>$(date)</p>"
}

Demo:https://vercel.import.sh/api/response-headers

JSON Response

It is common for serverless functions to communicate via JSON, so you can use the http_response_json function to set the Content-Type to application/json; charset=utf8.

handler() {
http_response_json
echo"{ \"title\": \"Current time\", \"body\": \"$(date)\" }"
}

Demo:https://vercel.import.sh/api/response-json

Status Code

The default status code is 200 but you can change it with the http_response_code function.

handler() {
http_response_code 500
echo"Internal Server Error from Bash!"
}

Demo:https://vercel.import.sh/api/response-status-code

Redirect

You can use the http_response_redirect function to set the location and, optionally, the status code. The default status code is 302 (temporary redirect) but you could use a permanent redirect by setting the second argument to 301.

handler() {
http_response_redirect "https://twitter.com/vercel" 301
echo"Redirecting..."
}

Demo:https://vercel.import.sh/api/redirect

Importing Dependencies

Bash, by itself, is not very useful for writing serverless function handler logic because it does not have a standard library. For this reason, import is installed and configured by default, which allows your script to easily include additional functionality and helper logic.

For example, the querystring import may be used to parse input parameters from the request URL:

import "querystring@1.3.0"handler() {
local path
local query
path="$(jq -r '.path'<"$1")"
query="$(querystring "$path")"echo"Querystring is: $query"
}

Demo:https://vercel.import.sh/api/querystring?a=b

Bash Version

With the Bash Builder, the handler script is executed using GNU Bash 4.

handler() {
bash --version
}

Demo:https://vercel.import.sh/api/bash-version

About

🐚 Bash Runtime for β–² Vercel serverless functions

Resources

Stars

94 stars

Watchers

5 watching

Forks

Releases

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Jun 8, 2026. It is now read-only.

Repository files navigation

The Bash Builder takes an entrypoint of a Bash function, imports its dependencies, and bundles them into a serverless function.

A simple "hello world" example:

handler() {
echo"Hello, from $(bash --version | head -n1)"
}

Demo:https://vercel.import.sh/api/hello

Usage

This example will detail creating an uppercase endpoint which will be accessed as https://my-deployment.url/api/uppercase. This endpoint will convert the provided querystring to uppercase using only Bash functions and standard Unix CLI tools.

Start by creating the project structure:

mkdir -p my-bash-project/api/uppercase
cd my-bash-project/api/uppercase

Inside the my-bash-project/api/uppercase directory, create an index.sh file with the following contents:

import "string@0.0.1"
import "querystring@1.3.0"handler() {
local path
path="$(jq -r '.path'<"$1")"
querystring "$path"| querystring_unescape | string_upper
}

The final step is to define a build that will take this entrypoint (index.sh), build it, and turn it into a serverless function using a vercel.json configuration in the root directory (my-bash-project):

{
"version": 2,
"functions": {
"api/*.sh": { "runtime": "vercel-bash@4.2.0" }
}
}

Import can be configured by adding options to the import property of the config. The IMPORT_ prefix must not be set in this case:

{
"version": 2,
"functions": {
"api/*.sh": {
"runtime": "vercel-bash@4.1.0",
"config": {
"import": {
"DEBUG": "1"
}
}
}
}
}

By passing in a querystring, the endpoint will return the uppercased version.

Demo:https://vercel.import.sh/api/uppercase?hello%20world

Build Logic

If your serverless function requires additional files to be added into the final bundle, an optional build() function may be defined.

Any files added to the current working directory at build-time will be included in the output serverless function.

build() {
date > build-time.txt
}
handler() {
echo"Build time: $(cat build-time.txt)"echo"Current time: $(date)"
}

Demo:https://vercel.import.sh/api/build

Response Headers

The default Content-Type is text/plain; charset=utf8 but you can change it by setting a response header.

handler() {
http_response_header "Content-Type""text/html; charset=utf8"echo"<h1>Current time</h1><p>$(date)</p>"
}

Demo:https://vercel.import.sh/api/response-headers

JSON Response

It is common for serverless functions to communicate via JSON, so you can use the http_response_json function to set the Content-Type to application/json; charset=utf8.

handler() {
http_response_json
echo"{ \"title\": \"Current time\", \"body\": \"$(date)\" }"
}

Demo:https://vercel.import.sh/api/response-json

Status Code

The default status code is 200 but you can change it with the http_response_code function.

handler() {
http_response_code 500
echo"Internal Server Error from Bash!"
}

Demo:https://vercel.import.sh/api/response-status-code

Redirect

You can use the http_response_redirect function to set the location and, optionally, the status code. The default status code is 302 (temporary redirect) but you could use a permanent redirect by setting the second argument to 301.

handler() {
http_response_redirect "https://twitter.com/vercel" 301
echo"Redirecting..."
}

Demo:https://vercel.import.sh/api/redirect

Importing Dependencies

Bash, by itself, is not very useful for writing serverless function handler logic because it does not have a standard library. For this reason, import is installed and configured by default, which allows your script to easily include additional functionality and helper logic.

For example, the querystring import may be used to parse input parameters from the request URL:

import "querystring@1.3.0"handler() {
local path
local query
path="$(jq -r '.path'<"$1")"
query="$(querystring "$path")"echo"Querystring is: $query"
}

Demo:https://vercel.import.sh/api/querystring?a=b

Bash Version

With the Bash Builder, the handler script is executed using GNU Bash 4.

handler() {
bash --version
}

Demo:https://vercel.import.sh/api/bash-version

About

🐚 Bash Runtime for β–² Vercel serverless functions

Resources

Stars

94 stars

Watchers

5 watching

Forks

Releases

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Jun 8, 2026. It is now read-only.

Repository files navigation

The Bash Builder takes an entrypoint of a Bash function, imports its dependencies, and bundles them into a serverless function.

A simple "hello world" example:

handler() {
echo"Hello, from $(bash --version | head -n1)"
}

Demo:https://vercel.import.sh/api/hello

Usage

This example will detail creating an uppercase endpoint which will be accessed as https://my-deployment.url/api/uppercase. This endpoint will convert the provided querystring to uppercase using only Bash functions and standard Unix CLI tools.

Start by creating the project structure:

mkdir -p my-bash-project/api/uppercase
cd my-bash-project/api/uppercase

Inside the my-bash-project/api/uppercase directory, create an index.sh file with the following contents:

import "string@0.0.1"
import "querystring@1.3.0"handler() {
local path
path="$(jq -r '.path'<"$1")"
querystring "$path"| querystring_unescape | string_upper
}

The final step is to define a build that will take this entrypoint (index.sh), build it, and turn it into a serverless function using a vercel.json configuration in the root directory (my-bash-project):

{
"version": 2,
"functions": {
"api/*.sh": { "runtime": "vercel-bash@4.2.0" }
}
}

Import can be configured by adding options to the import property of the config. The IMPORT_ prefix must not be set in this case:

{
"version": 2,
"functions": {
"api/*.sh": {
"runtime": "vercel-bash@4.1.0",
"config": {
"import": {
"DEBUG": "1"
}
}
}
}
}

By passing in a querystring, the endpoint will return the uppercased version.

Demo:https://vercel.import.sh/api/uppercase?hello%20world

Build Logic

If your serverless function requires additional files to be added into the final bundle, an optional build() function may be defined.

Any files added to the current working directory at build-time will be included in the output serverless function.

build() {
date > build-time.txt
}
handler() {
echo"Build time: $(cat build-time.txt)"echo"Current time: $(date)"
}

Demo:https://vercel.import.sh/api/build

Response Headers

The default Content-Type is text/plain; charset=utf8 but you can change it by setting a response header.

handler() {
http_response_header "Content-Type""text/html; charset=utf8"echo"<h1>Current time</h1><p>$(date)</p>"
}

Demo:https://vercel.import.sh/api/response-headers

JSON Response

It is common for serverless functions to communicate via JSON, so you can use the http_response_json function to set the Content-Type to application/json; charset=utf8.

handler() {
http_response_json
echo"{ \"title\": \"Current time\", \"body\": \"$(date)\" }"
}

Demo:https://vercel.import.sh/api/response-json

Status Code

The default status code is 200 but you can change it with the http_response_code function.

handler() {
http_response_code 500
echo"Internal Server Error from Bash!"
}

Demo:https://vercel.import.sh/api/response-status-code

Redirect

You can use the http_response_redirect function to set the location and, optionally, the status code. The default status code is 302 (temporary redirect) but you could use a permanent redirect by setting the second argument to 301.

handler() {
http_response_redirect "https://twitter.com/vercel" 301
echo"Redirecting..."
}

Demo:https://vercel.import.sh/api/redirect

Importing Dependencies

Bash, by itself, is not very useful for writing serverless function handler logic because it does not have a standard library. For this reason, import is installed and configured by default, which allows your script to easily include additional functionality and helper logic.

For example, the querystring import may be used to parse input parameters from the request URL:

import "querystring@1.3.0"handler() {
local path
local query
path="$(jq -r '.path'<"$1")"
query="$(querystring "$path")"echo"Querystring is: $query"
}

Demo:https://vercel.import.sh/api/querystring?a=b

Bash Version

With the Bash Builder, the handler script is executed using GNU Bash 4.

handler() {
bash --version
}

Demo:https://vercel.import.sh/api/bash-version

About

🐚 Bash Runtime for β–² Vercel serverless functions

Resources

Stars

94 stars

Watchers

5 watching

Forks

Releases

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
This repository was archived by the owner on Jun 8, 2026. It is now read-only.

Repository files navigation

The Bash Builder takes an entrypoint of a Bash function, imports its dependencies, and bundles them into a serverless function.

A simple "hello world" example:

handler() {
echo"Hello, from $(bash --version | head -n1)"
}

Demo:https://vercel.import.sh/api/hello

Usage

This example will detail creating an uppercase endpoint which will be accessed as https://my-deployment.url/api/uppercase. This endpoint will convert the provided querystring to uppercase using only Bash functions and standard Unix CLI tools.

Start by creating the project structure:

mkdir -p my-bash-project/api/uppercase
cd my-bash-project/api/uppercase

Inside the my-bash-project/api/uppercase directory, create an index.sh file with the following contents:

import "string@0.0.1"
import "querystring@1.3.0"handler() {
local path
path="$(jq -r '.path'<"$1")"
querystring "$path"| querystring_unescape | string_upper
}

The final step is to define a build that will take this entrypoint (index.sh), build it, and turn it into a serverless function using a vercel.json configuration in the root directory (my-bash-project):

{
"version": 2,
"functions": {
"api/*.sh": { "runtime": "vercel-bash@4.2.0" }
}
}

Import can be configured by adding options to the import property of the config. The IMPORT_ prefix must not be set in this case:

{
"version": 2,
"functions": {
"api/*.sh": {
"runtime": "vercel-bash@4.1.0",
"config": {
"import": {
"DEBUG": "1"
}
}
}
}
}

By passing in a querystring, the endpoint will return the uppercased version.

Demo:https://vercel.import.sh/api/uppercase?hello%20world

Build Logic

If your serverless function requires additional files to be added into the final bundle, an optional build() function may be defined.

Any files added to the current working directory at build-time will be included in the output serverless function.

build() {
date > build-time.txt
}
handler() {
echo"Build time: $(cat build-time.txt)"echo"Current time: $(date)"
}

Demo:https://vercel.import.sh/api/build

Response Headers

The default Content-Type is text/plain; charset=utf8 but you can change it by setting a response header.

handler() {
http_response_header "Content-Type""text/html; charset=utf8"echo"<h1>Current time</h1><p>$(date)</p>"
}

Demo:https://vercel.import.sh/api/response-headers

JSON Response

It is common for serverless functions to communicate via JSON, so you can use the http_response_json function to set the Content-Type to application/json; charset=utf8.

handler() {
http_response_json
echo"{ \"title\": \"Current time\", \"body\": \"$(date)\" }"
}

Demo:https://vercel.import.sh/api/response-json

Status Code

The default status code is 200 but you can change it with the http_response_code function.

handler() {
http_response_code 500
echo"Internal Server Error from Bash!"
}

Demo:https://vercel.import.sh/api/response-status-code

Redirect

You can use the http_response_redirect function to set the location and, optionally, the status code. The default status code is 302 (temporary redirect) but you could use a permanent redirect by setting the second argument to 301.

handler() {
http_response_redirect "https://twitter.com/vercel" 301
echo"Redirecting..."
}

Demo:https://vercel.import.sh/api/redirect

Importing Dependencies

Bash, by itself, is not very useful for writing serverless function handler logic because it does not have a standard library. For this reason, import is installed and configured by default, which allows your script to easily include additional functionality and helper logic.

For example, the querystring import may be used to parse input parameters from the request URL:

import "querystring@1.3.0"handler() {
local path
local query
path="$(jq -r '.path'<"$1")"
query="$(querystring "$path")"echo"Querystring is: $query"
}

Demo:https://vercel.import.sh/api/querystring?a=b

Bash Version

With the Bash Builder, the handler script is executed using GNU Bash 4.

handler() {
bash --version
}

Demo:https://vercel.import.sh/api/bash-version

About

🐚 Bash Runtime for β–² Vercel serverless functions

Resources

Stars

94 stars

Watchers

5 watching

Forks

Releases

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Jun 8, 2026. It is now read-only.

Repository files navigation

The Bash Builder takes an entrypoint of a Bash function, imports its dependencies, and bundles them into a serverless function.

A simple "hello world" example:

handler() {
echo"Hello, from $(bash --version | head -n1)"
}

Demo:https://vercel.import.sh/api/hello

Usage

This example will detail creating an uppercase endpoint which will be accessed as https://my-deployment.url/api/uppercase. This endpoint will convert the provided querystring to uppercase using only Bash functions and standard Unix CLI tools.

Start by creating the project structure:

mkdir -p my-bash-project/api/uppercase
cd my-bash-project/api/uppercase

Inside the my-bash-project/api/uppercase directory, create an index.sh file with the following contents:

import "string@0.0.1"
import "querystring@1.3.0"handler() {
local path
path="$(jq -r '.path'<"$1")"
querystring "$path"| querystring_unescape | string_upper
}

The final step is to define a build that will take this entrypoint (index.sh), build it, and turn it into a serverless function using a vercel.json configuration in the root directory (my-bash-project):

{
"version": 2,
"functions": {
"api/*.sh": { "runtime": "vercel-bash@4.2.0" }
}
}

Import can be configured by adding options to the import property of the config. The IMPORT_ prefix must not be set in this case:

{
"version": 2,
"functions": {
"api/*.sh": {
"runtime": "vercel-bash@4.1.0",
"config": {
"import": {
"DEBUG": "1"
}
}
}
}
}

By passing in a querystring, the endpoint will return the uppercased version.

Demo:https://vercel.import.sh/api/uppercase?hello%20world

Build Logic

If your serverless function requires additional files to be added into the final bundle, an optional build() function may be defined.

Any files added to the current working directory at build-time will be included in the output serverless function.

build() {
date > build-time.txt
}
handler() {
echo"Build time: $(cat build-time.txt)"echo"Current time: $(date)"
}

Demo:https://vercel.import.sh/api/build

Response Headers

The default Content-Type is text/plain; charset=utf8 but you can change it by setting a response header.

handler() {
http_response_header "Content-Type""text/html; charset=utf8"echo"<h1>Current time</h1><p>$(date)</p>"
}

Demo:https://vercel.import.sh/api/response-headers

JSON Response

It is common for serverless functions to communicate via JSON, so you can use the http_response_json function to set the Content-Type to application/json; charset=utf8.

handler() {
http_response_json
echo"{ \"title\": \"Current time\", \"body\": \"$(date)\" }"
}

Demo:https://vercel.import.sh/api/response-json

Status Code

The default status code is 200 but you can change it with the http_response_code function.

handler() {
http_response_code 500
echo"Internal Server Error from Bash!"
}

Demo:https://vercel.import.sh/api/response-status-code

Redirect

You can use the http_response_redirect function to set the location and, optionally, the status code. The default status code is 302 (temporary redirect) but you could use a permanent redirect by setting the second argument to 301.

handler() {
http_response_redirect "https://twitter.com/vercel" 301
echo"Redirecting..."
}

Demo:https://vercel.import.sh/api/redirect

Importing Dependencies

Bash, by itself, is not very useful for writing serverless function handler logic because it does not have a standard library. For this reason, import is installed and configured by default, which allows your script to easily include additional functionality and helper logic.

For example, the querystring import may be used to parse input parameters from the request URL:

import "querystring@1.3.0"handler() {
local path
local query
path="$(jq -r '.path'<"$1")"
query="$(querystring "$path")"echo"Querystring is: $query"
}

Demo:https://vercel.import.sh/api/querystring?a=b

Bash Version

With the Bash Builder, the handler script is executed using GNU Bash 4.

handler() {
bash --version
}

Demo:https://vercel.import.sh/api/bash-version

About

🐚 Bash Runtime for β–² Vercel serverless functions

Resources

Stars

94 stars

Watchers

5 watching

Forks

Releases

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Jun 8, 2026. It is now read-only.

Repository files navigation

The Bash Builder takes an entrypoint of a Bash function, imports its dependencies, and bundles them into a serverless function.

A simple "hello world" example:

handler() {
echo"Hello, from $(bash --version | head -n1)"
}

Demo:https://vercel.import.sh/api/hello

Usage

This example will detail creating an uppercase endpoint which will be accessed as https://my-deployment.url/api/uppercase. This endpoint will convert the provided querystring to uppercase using only Bash functions and standard Unix CLI tools.

Start by creating the project structure:

mkdir -p my-bash-project/api/uppercase
cd my-bash-project/api/uppercase

Inside the my-bash-project/api/uppercase directory, create an index.sh file with the following contents:

import "string@0.0.1"
import "querystring@1.3.0"handler() {
local path
path="$(jq -r '.path'<"$1")"
querystring "$path"| querystring_unescape | string_upper
}

The final step is to define a build that will take this entrypoint (index.sh), build it, and turn it into a serverless function using a vercel.json configuration in the root directory (my-bash-project):

{
"version": 2,
"functions": {
"api/*.sh": { "runtime": "vercel-bash@4.2.0" }
}
}

Import can be configured by adding options to the import property of the config. The IMPORT_ prefix must not be set in this case:

{
"version": 2,
"functions": {
"api/*.sh": {
"runtime": "vercel-bash@4.1.0",
"config": {
"import": {
"DEBUG": "1"
}
}
}
}
}

By passing in a querystring, the endpoint will return the uppercased version.

Demo:https://vercel.import.sh/api/uppercase?hello%20world

Build Logic

If your serverless function requires additional files to be added into the final bundle, an optional build() function may be defined.

Any files added to the current working directory at build-time will be included in the output serverless function.

build() {
date > build-time.txt
}
handler() {
echo"Build time: $(cat build-time.txt)"echo"Current time: $(date)"
}

Demo:https://vercel.import.sh/api/build

Response Headers

The default Content-Type is text/plain; charset=utf8 but you can change it by setting a response header.

handler() {
http_response_header "Content-Type""text/html; charset=utf8"echo"<h1>Current time</h1><p>$(date)</p>"
}

Demo:https://vercel.import.sh/api/response-headers

JSON Response

It is common for serverless functions to communicate via JSON, so you can use the http_response_json function to set the Content-Type to application/json; charset=utf8.

handler() {
http_response_json
echo"{ \"title\": \"Current time\", \"body\": \"$(date)\" }"
}

Demo:https://vercel.import.sh/api/response-json

Status Code

The default status code is 200 but you can change it with the http_response_code function.

handler() {
http_response_code 500
echo"Internal Server Error from Bash!"
}

Demo:https://vercel.import.sh/api/response-status-code

Redirect

You can use the http_response_redirect function to set the location and, optionally, the status code. The default status code is 302 (temporary redirect) but you could use a permanent redirect by setting the second argument to 301.

handler() {
http_response_redirect "https://twitter.com/vercel" 301
echo"Redirecting..."
}

Demo:https://vercel.import.sh/api/redirect

Importing Dependencies

Bash, by itself, is not very useful for writing serverless function handler logic because it does not have a standard library. For this reason, import is installed and configured by default, which allows your script to easily include additional functionality and helper logic.

For example, the querystring import may be used to parse input parameters from the request URL:

import "querystring@1.3.0"handler() {
local path
local query
path="$(jq -r '.path'<"$1")"
query="$(querystring "$path")"echo"Querystring is: $query"
}

Demo:https://vercel.import.sh/api/querystring?a=b

Bash Version

With the Bash Builder, the handler script is executed using GNU Bash 4.

handler() {
bash --version
}

Demo:https://vercel.import.sh/api/bash-version

About

🐚 Bash Runtime for β–² Vercel serverless functions

Resources

Stars

94 stars

Watchers

5 watching

Forks

Releases

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
This repository was archived by the owner on Jun 8, 2026. It is now read-only.

Repository files navigation

The Bash Builder takes an entrypoint of a Bash function, imports its dependencies, and bundles them into a serverless function.

A simple "hello world" example:

handler() {
echo"Hello, from $(bash --version | head -n1)"
}

Demo:https://vercel.import.sh/api/hello

Usage

This example will detail creating an uppercase endpoint which will be accessed as https://my-deployment.url/api/uppercase. This endpoint will convert the provided querystring to uppercase using only Bash functions and standard Unix CLI tools.

Start by creating the project structure:

mkdir -p my-bash-project/api/uppercase
cd my-bash-project/api/uppercase

Inside the my-bash-project/api/uppercase directory, create an index.sh file with the following contents:

import "string@0.0.1"
import "querystring@1.3.0"handler() {
local path
path="$(jq -r '.path'<"$1")"
querystring "$path"| querystring_unescape | string_upper
}

The final step is to define a build that will take this entrypoint (index.sh), build it, and turn it into a serverless function using a vercel.json configuration in the root directory (my-bash-project):

{
"version": 2,
"functions": {
"api/*.sh": { "runtime": "vercel-bash@4.2.0" }
}
}

Import can be configured by adding options to the import property of the config. The IMPORT_ prefix must not be set in this case:

{
"version": 2,
"functions": {
"api/*.sh": {
"runtime": "vercel-bash@4.1.0",
"config": {
"import": {
"DEBUG": "1"
}
}
}
}
}

By passing in a querystring, the endpoint will return the uppercased version.

Demo:https://vercel.import.sh/api/uppercase?hello%20world

Build Logic

If your serverless function requires additional files to be added into the final bundle, an optional build() function may be defined.

Any files added to the current working directory at build-time will be included in the output serverless function.

build() {
date > build-time.txt
}
handler() {
echo"Build time: $(cat build-time.txt)"echo"Current time: $(date)"
}

Demo:https://vercel.import.sh/api/build

Response Headers

The default Content-Type is text/plain; charset=utf8 but you can change it by setting a response header.

handler() {
http_response_header "Content-Type""text/html; charset=utf8"echo"<h1>Current time</h1><p>$(date)</p>"
}

Demo:https://vercel.import.sh/api/response-headers

JSON Response

It is common for serverless functions to communicate via JSON, so you can use the http_response_json function to set the Content-Type to application/json; charset=utf8.

handler() {
http_response_json
echo"{ \"title\": \"Current time\", \"body\": \"$(date)\" }"
}

Demo:https://vercel.import.sh/api/response-json

Status Code

The default status code is 200 but you can change it with the http_response_code function.

handler() {
http_response_code 500
echo"Internal Server Error from Bash!"
}

Demo:https://vercel.import.sh/api/response-status-code

Redirect

You can use the http_response_redirect function to set the location and, optionally, the status code. The default status code is 302 (temporary redirect) but you could use a permanent redirect by setting the second argument to 301.

handler() {
http_response_redirect "https://twitter.com/vercel" 301
echo"Redirecting..."
}

Demo:https://vercel.import.sh/api/redirect

Importing Dependencies

Bash, by itself, is not very useful for writing serverless function handler logic because it does not have a standard library. For this reason, import is installed and configured by default, which allows your script to easily include additional functionality and helper logic.

For example, the querystring import may be used to parse input parameters from the request URL:

import "querystring@1.3.0"handler() {
local path
local query
path="$(jq -r '.path'<"$1")"
query="$(querystring "$path")"echo"Querystring is: $query"
}

Demo:https://vercel.import.sh/api/querystring?a=b

Bash Version

With the Bash Builder, the handler script is executed using GNU Bash 4.

handler() {
bash --version
}

Demo:https://vercel.import.sh/api/bash-version

About

🐚 Bash Runtime for β–² Vercel serverless functions

Resources

Stars

94 stars

Watchers

5 watching

Forks

Releases

Used by

Contributors

Languages