diff --git a/assets/javascripts/news.json b/assets/javascripts/news.json
index a8217c2b..f011506e 100644
--- a/assets/javascripts/news.json
+++ b/assets/javascripts/news.json
@@ -1,4 +1,8 @@
[
+ [
+ "2021-12-05",
+ "New documentation: esbuild"
+ ],
[
"2021-12-04",
"New documentation: Vite"
diff --git a/assets/javascripts/templates/pages/about_tmpl.coffee b/assets/javascripts/templates/pages/about_tmpl.coffee
index e5349e9c..144b4622 100644
--- a/assets/javascripts/templates/pages/about_tmpl.coffee
+++ b/assets/javascripts/templates/pages/about_tmpl.coffee
@@ -291,6 +291,11 @@ credits = [
'2010-2021 Ericsson AB',
'Apache',
'https://raw.githubusercontent.com/erlang/otp/maint/LICENSE.txt'
+ ], [
+ 'esbulid',
+ '2020 Evan Wallace',
+ 'MIT',
+ 'https://raw.githubusercontent.com/evanw/esbuild/blob/master/LICENSE.md'
], [
'ESLint',
'OpenJS Foundation and other contributors',
diff --git a/lib/docs/filters/esbuild/clean_html.rb b/lib/docs/filters/esbuild/clean_html.rb
new file mode 100644
index 00000000..068c17cb
--- /dev/null
+++ b/lib/docs/filters/esbuild/clean_html.rb
@@ -0,0 +1,19 @@
+module Docs
+ class Esbuild
+ class CleanHtmlFilter < Filter
+ def call
+ css('figure.bench').remove
+ css('.permalink').remove
+ css('.switcher').remove
+ css('pre').each do |node|
+ node.content = node.content
+ node['data-language'] = 'javascript'
+ node['data-language'] = 'sh' if node['class'] && node['class'].include?('cli')
+ node['data-language'] = 'go' if node['class'] && node['class'].include?('go')
+ node['class'] = nil
+ end
+ doc
+ end
+ end
+ end
+end
diff --git a/lib/docs/filters/esbuild/entries.rb b/lib/docs/filters/esbuild/entries.rb
new file mode 100644
index 00000000..26cce239
--- /dev/null
+++ b/lib/docs/filters/esbuild/entries.rb
@@ -0,0 +1,21 @@
+module Docs
+ class Esbuild
+ class EntriesFilter < Docs::EntriesFilter
+ def name
+ at_css('h1').content
+ end
+ def type
+ at_css('h1').content
+ end
+
+ def additional_entries
+ entries = []
+ type = at_css('h1').content
+ css('h2[id], h3[id]').each do |node|
+ entries << [node.content.gsub(/^#/, ''), node['id'], type]
+ end
+ entries
+ end
+ end
+ end
+end
diff --git a/lib/docs/scrapers/esbuild.rb b/lib/docs/scrapers/esbuild.rb
new file mode 100644
index 00000000..c495518e
--- /dev/null
+++ b/lib/docs/scrapers/esbuild.rb
@@ -0,0 +1,29 @@
+module Docs
+ class Esbuild < UrlScraper
+ self.name = 'esbuild'
+ self.slug = 'esbuild'
+ self.type = 'simple'
+ self.links = {
+ home: 'https://esbuild.github.io/',
+ code: 'https://github.com/evanw/esbuild'
+ }
+
+ options[:container] = 'main'
+ options[:root_title] = 'esbuild'
+
+ options[:attribution] = <<-HTML
+ © 2020 Evan Wallace
+ Licensed under the MIT License.
+ HTML
+
+ version do
+ self.release = '0.14.2'
+ self.base_url = 'https://esbuild.github.io/'
+ html_filters.push 'esbuild/clean_html', 'esbuild/entries'
+ end
+
+ def get_latest_version(opts)
+ get_npm_version('esbuild', opts)
+ end
+ end
+end
diff --git a/public/icons/docs/esbuild/16.png b/public/icons/docs/esbuild/16.png
new file mode 100644
index 00000000..c2891b01
Binary files /dev/null and b/public/icons/docs/esbuild/16.png differ
diff --git a/public/icons/docs/esbuild/16@2x.png b/public/icons/docs/esbuild/16@2x.png
new file mode 100644
index 00000000..9b233f85
Binary files /dev/null and b/public/icons/docs/esbuild/16@2x.png differ
diff --git a/public/icons/docs/esbuild/SOURCE b/public/icons/docs/esbuild/SOURCE
new file mode 100644
index 00000000..721ff1f5
--- /dev/null
+++ b/public/icons/docs/esbuild/SOURCE
@@ -0,0 +1 @@
+https://esbuild.github.io/favicon.svg