<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:media="http://search.yahoo.com/mrss/">
  <channel>
    <title>GitHub Haskell Weekly Trending</title>
    <description>Weekly Trending of Haskell in GitHub</description>
    <pubDate>Fri, 15 May 2026 01:48:13 GMT</pubDate>
    <link>http://mshibanami.github.io/GitHubTrendingRSS</link>
    
    <item>
      <title>monoscope-tech/monoscope</title>
      <link>https://github.com/monoscope-tech/monoscope</link>
      <description>&lt;p&gt;Monoscope lets you ingest and explore your logs, traces and metrics. We store these in S3 compatible buckets. Query in natural language via LLMs.&lt;/p&gt;&lt;hr&gt;&lt;div align=&quot;center&quot;&gt; 
 &lt;img src=&quot;https://raw.githubusercontent.com/monoscope-tech/monoscope/master/docs/monoscope.svg?sanitize=true&quot; alt=&quot;Monoscope Logo&quot; width=&quot;250&quot; /&gt; 
 &lt;h3&gt;Open-source observability platform with S3 storage&lt;/h3&gt; 
 &lt;p&gt;Ingest and explore logs, traces, and metrics stored in your S3 buckets. Query with natural language. Create AI agents that detect anomalies and send daily/weekly reports to your inbox.&lt;/p&gt; 
 &lt;p&gt;&lt;a href=&quot;https://github.com/monoscope-tech/monoscope/releases&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/v/release/monoscope-tech/monoscope?include_prereleases&quot; alt=&quot;GitHub Release&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://raw.githubusercontent.com/monoscope-tech/monoscope/master/LICENSE&quot;&gt;&lt;img src=&quot;https://img.shields.io/badge/license-AGPL--3.0-blue.svg?sanitize=true&quot; alt=&quot;License&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://www.haskell.org/&quot;&gt;&lt;img src=&quot;https://img.shields.io/badge/Built%20with-Haskell-5e5086?logo=haskell&quot; alt=&quot;Haskell&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://discord.gg/BSFCaUHxt4&quot;&gt;&lt;img src=&quot;https://img.shields.io/discord/904634773329297429?color=7289da&amp;amp;logo=discord&amp;amp;logoColor=white&quot; alt=&quot;Discord&quot; /&gt;&lt;/a&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;a href=&quot;https://monoscope.tech&quot;&gt;&lt;strong&gt;Website&lt;/strong&gt;&lt;/a&gt; • &lt;a href=&quot;https://app.monoscope.tech/p/00000000-0000-0000-0000-000000000000/log_explorer&quot;&gt;&lt;strong&gt;Playground&lt;/strong&gt;&lt;/a&gt; • &lt;a href=&quot;https://discord.gg/BSFCaUHxt4&quot;&gt;&lt;strong&gt;Discord&lt;/strong&gt;&lt;/a&gt; • &lt;a href=&quot;https://x.com/monoscope-tech&quot;&gt;&lt;strong&gt;Twitter&lt;/strong&gt;&lt;/a&gt; • &lt;a href=&quot;https://docs.monoscope.tech&quot;&gt;&lt;strong&gt;Documentation&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;/div&gt; 
&lt;div align=&quot;center&quot; style=&quot;margin-top: 1em; margin-bottom: 1em;&quot;&gt; 
 &lt;a href=&quot;https://raw.githubusercontent.com/monoscope-tech/monoscope/master/#what-is-monoscope&quot;&gt;What is Monoscope?&lt;/a&gt; • 
 &lt;a href=&quot;https://raw.githubusercontent.com/monoscope-tech/monoscope/master/#cloud-vs-self-hosted&quot;&gt;Cloud vs Self-hosted&lt;/a&gt; • 
 &lt;a href=&quot;https://raw.githubusercontent.com/monoscope-tech/monoscope/master/#quick-start&quot;&gt;Quick Start&lt;/a&gt; • 
 &lt;a href=&quot;https://raw.githubusercontent.com/monoscope-tech/monoscope/master/#ai-agents--reports&quot;&gt;AI Agents&lt;/a&gt; • 
 &lt;a href=&quot;https://raw.githubusercontent.com/monoscope-tech/monoscope/master/#roadmap&quot;&gt;Roadmap&lt;/a&gt; 
&lt;/div&gt; 
&lt;br /&gt; 
&lt;div align=&quot;center&quot;&gt; 
 &lt;img width=&quot;100%&quot; src=&quot;https://github.com/user-attachments/assets/6175c23b-f3ac-450a-9ae3-4b86371f4f54&quot; alt=&quot;Monoscope Dashboard&quot; /&gt; 
&lt;/div&gt; 
&lt;br /&gt; 
&lt;h2&gt;What is Monoscope?&lt;/h2&gt; 
&lt;p&gt;Monoscope is an open-source observability platform that stores your telemetry data in S3-compatible storage. Self-host it or use our &lt;a href=&quot;https://monoscope.tech&quot;&gt;cloud offering&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Core capabilities:&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;💰 &lt;strong&gt;S3 storage&lt;/strong&gt; — Store years of logs, metrics, and traces affordably in your own S3 buckets&lt;/li&gt; 
 &lt;li&gt;💬 &lt;strong&gt;Natural language queries&lt;/strong&gt; — Search your data using plain English via LLMs&lt;/li&gt; 
 &lt;li&gt;🤖 &lt;strong&gt;AI agents&lt;/strong&gt; — Create agents that run on a schedule to detect anomalies and surface insights&lt;/li&gt; 
 &lt;li&gt;📧 &lt;strong&gt;Email reports&lt;/strong&gt; — Receive daily/weekly summaries of important events and anomalies&lt;/li&gt; 
 &lt;li&gt;🔭 &lt;strong&gt;OpenTelemetry native&lt;/strong&gt; — 750+ integrations out of the box&lt;/li&gt; 
 &lt;li&gt;⚡ &lt;strong&gt;Live tail&lt;/strong&gt; — Stream logs and traces in real-time&lt;/li&gt; 
 &lt;li&gt;🕵️ &lt;strong&gt;Unified view&lt;/strong&gt; — Correlate logs, metrics, traces, and session replays in one place&lt;/li&gt; 
&lt;/ul&gt; 
&lt;br /&gt; 
&lt;h2&gt;Cloud vs Self-hosted&lt;/h2&gt; 
&lt;p&gt;In both options, you bring your own S3 buckets—your data stays yours.&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt; 
   &lt;th&gt;&lt;/th&gt; 
   &lt;th&gt;Cloud&lt;/th&gt; 
   &lt;th&gt;Self-hosted&lt;/th&gt; 
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;strong&gt;Storage&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;Your S3 buckets&lt;/td&gt; 
   &lt;td&gt;Your S3 buckets&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;strong&gt;Compute&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;Managed by us&lt;/td&gt; 
   &lt;td&gt;You manage&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;strong&gt;Auth &amp;amp; SSO&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;Built-in&lt;/td&gt; 
   &lt;td&gt;DIY&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;strong&gt;Alert channels&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;Slack, PagerDuty, etc.&lt;/td&gt; 
   &lt;td&gt;Basic email&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;&lt;a href=&quot;https://monoscope.tech/pricing&quot;&gt;Usage-based&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;Free (AGPL-3.0)&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;→ &lt;a href=&quot;https://monoscope.tech&quot;&gt;Start free on Cloud&lt;/a&gt; or continue below to self-host.&lt;/p&gt; 
&lt;br /&gt; 
&lt;h2&gt;Quick Start&lt;/h2&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git clone https://github.com/monoscope-tech/monoscope.git
cd monoscope
docker-compose up
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Visit &lt;code&gt;http://localhost:8080&lt;/code&gt; (default: admin/changeme)&lt;/p&gt; 
&lt;h3&gt;Send Test Data&lt;/h3&gt; 
&lt;p&gt;Populate your dashboard with test telemetry:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;monoscope auth login

# Single event — see your message appear in the dashboard
monoscope send-event -m &quot;Hello from Monoscope&quot;

# Sustained load — stress-test the pipeline
monoscope telemetrygen --kind=trace --rate=5 --count=50
&lt;/code&gt;&lt;/pre&gt; 
&lt;br /&gt; 
&lt;h2&gt;CLI&lt;/h2&gt; 
&lt;p&gt;Manage your Monoscope project from the terminal — search logs, query metrics, manage monitors and dashboards, triage issues, and more.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;curl monoscope.tech/install.sh | sh
monoscope auth login
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;See the &lt;a href=&quot;https://raw.githubusercontent.com/monoscope-tech/monoscope/master/docs/cli.md&quot;&gt;CLI reference&lt;/a&gt; for the full command list.&lt;/p&gt; 
&lt;h3&gt;Agentic pipeline&lt;/h3&gt; 
&lt;p&gt;Every CLI command emits a stable JSON envelope, so you can chain discovery → search → triage without manual munging. This is the same pipeline a Claude Code skill runs end-to-end:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 1. What services exist? (Precomputed; no aggregation query needed.)
SVC=$(monoscope facets resource.service.name --top 1 \
        | jq -r &#39;.[&quot;resource.service.name&quot;][0].value&#39;)

# 2. Grab one error event from that service — id only, ready to chain.
ID=$(monoscope logs search &#39;severity.text==&quot;error&quot;&#39; \
        --service &quot;$SVC&quot; --first --id-only)

# 3. Pull the surrounding 5 minutes of traffic, with a per-trace summary
#    showing which other services were affected.
monoscope events context --window 5m --summary \
  --at &quot;$(monoscope events get &quot;$ID&quot; | jq -r .timestamp)&quot; \
  | jq &#39;.traces | sort_by(-.error_count) | .[0:3]&#39;

# 4. Acknowledge the open issue once you have a hypothesis.
monoscope issues list --service &quot;$SVC&quot; --status open \
  | jq -r &#39;.data[].id&#39; | head -3 \
  | xargs -I {} monoscope issues ack {}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Each step&#39;s output shape is documented and stable:&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt; 
   &lt;th&gt;Command&lt;/th&gt; 
   &lt;th&gt;Envelope&lt;/th&gt; 
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;code&gt;facets [FIELD]&lt;/code&gt;&lt;/td&gt; 
   &lt;td&gt;&lt;code&gt;{&amp;lt;field_path&amp;gt;: [{value, count}, ...]}&lt;/code&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;code&gt;events search&lt;/code&gt; (and &lt;code&gt;logs&lt;/code&gt;/&lt;code&gt;traces&lt;/code&gt;)&lt;/td&gt; 
   &lt;td&gt;&lt;code&gt;{events: [...], count, has_more, cursor}&lt;/code&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;code&gt;events context --summary&lt;/code&gt;&lt;/td&gt; 
   &lt;td&gt;&lt;code&gt;{events, count, traces: [{trace_id, services, span_count, error_count}]}&lt;/code&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;code&gt;issues list&lt;/code&gt;, &lt;code&gt;monitors list&lt;/code&gt;, ...&lt;/td&gt; 
   &lt;td&gt;&lt;code&gt;{data: [...], pagination: {has_more, total, cursor, page, per_page}}&lt;/code&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;code&gt;auth status&lt;/code&gt; (agent mode)&lt;/td&gt; 
   &lt;td&gt;&lt;code&gt;{authenticated, method, api_url, project}&lt;/code&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;Set &lt;code&gt;MONOSCOPE_AGENT_MODE=1&lt;/code&gt; (or run with &lt;code&gt;--agent&lt;/code&gt;) to force JSON output and disable interactive prompts — auto-detected when &lt;code&gt;CI&lt;/code&gt; or &lt;code&gt;CLAUDE_CODE&lt;/code&gt; is set.&lt;/p&gt; 
&lt;h3&gt;Claude Code Skills&lt;/h3&gt; 
&lt;p&gt;Let Claude investigate incidents, triage alerts, and write KQL queries using the &lt;code&gt;monoscope&lt;/code&gt; CLI — install the skills plugin:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Claude Code
claude plugin marketplace add monoscope-tech/skills
claude plugin install monoscope-skills@monoscope-skills

# or via npx (Cursor, Cline, Copilot, and other agents)
npx skills add monoscope-tech/skills
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Restart Claude Code after installation. Skills activate automatically when relevant — e.g. &lt;em&gt;&quot;investigate the 500 errors in payment-api&quot;&lt;/em&gt; or &lt;em&gt;&quot;do an on-call sweep&quot;&lt;/em&gt;.&lt;/p&gt; 
&lt;p&gt;See &lt;a href=&quot;https://github.com/monoscope-tech/skills&quot;&gt;github.com/monoscope-tech/skills&lt;/a&gt; for the full skill list and documentation.&lt;/p&gt; 
&lt;br /&gt; 
&lt;h2&gt;MCP Server&lt;/h2&gt; 
&lt;p&gt;Monoscope exposes itself as a &lt;a href=&quot;https://modelcontextprotocol.io/&quot;&gt;Model Context Protocol&lt;/a&gt; server at &lt;code&gt;/api/v1/mcp&lt;/code&gt;, so any MCP-aware client (Claude Desktop, Cursor, Cline, custom agents) can search events, manage monitors and dashboards, triage issues, and run composite workflows like &lt;code&gt;search_events_nl&lt;/code&gt; (natural-language → KQL) and &lt;code&gt;analyze_issue&lt;/code&gt; (LLM-assisted root-cause).&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
  &quot;mcpServers&quot;: {
    &quot;monoscope&quot;: {
      &quot;url&quot;: &quot;https://api.monoscope.tech/api/v1/mcp&quot;,
      &quot;headers&quot;: { &quot;Authorization&quot;: &quot;Bearer YOUR_API_KEY&quot; }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Every public REST endpoint is auto-registered as a verb-first tool (&lt;code&gt;list_monitors&lt;/code&gt;, &lt;code&gt;search_events&lt;/code&gt;, &lt;code&gt;mute_monitor&lt;/code&gt;, …). See the &lt;a href=&quot;https://raw.githubusercontent.com/monoscope-tech/monoscope/master/docs/mcp.md&quot;&gt;MCP reference&lt;/a&gt; for the full protocol, tool catalog, and examples.&lt;/p&gt; 
&lt;br /&gt; 
&lt;h2&gt;Integration&lt;/h2&gt; 
&lt;h3&gt;Auto-instrument your apps&lt;/h3&gt; 
&lt;details&gt; 
 &lt;summary&gt;&lt;b&gt;Python&lt;/b&gt;&lt;/summary&gt; 
 &lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;pip install opentelemetry-distro opentelemetry-exporter-otlp
opentelemetry-bootstrap -a install
OTEL_SERVICE_NAME=&quot;my-app&quot; \
OTEL_EXPORTER_OTLP_ENDPOINT=&quot;http://localhost:4317&quot; \
opentelemetry-instrument python myapp.py
&lt;/code&gt;&lt;/pre&gt; 
&lt;/details&gt; 
&lt;details&gt; 
 &lt;summary&gt;&lt;b&gt;Node.js&lt;/b&gt;&lt;/summary&gt; 
 &lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;npm install --save @opentelemetry/auto-instrumentations-node
OTEL_SERVICE_NAME=&quot;my-app&quot; \
OTEL_EXPORTER_OTLP_ENDPOINT=&quot;http://localhost:4317&quot; \
node --require @opentelemetry/auto-instrumentations-node/register app.js
&lt;/code&gt;&lt;/pre&gt; 
&lt;/details&gt; 
&lt;details&gt; 
 &lt;summary&gt;&lt;b&gt;Java&lt;/b&gt;&lt;/summary&gt; 
 &lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;curl -L https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar -o otel-agent.jar
OTEL_SERVICE_NAME=&quot;my-app&quot; \
OTEL_EXPORTER_OTLP_ENDPOINT=&quot;http://localhost:4317&quot; \
java -javaagent:otel-agent.jar -jar myapp.jar
&lt;/code&gt;&lt;/pre&gt; 
&lt;/details&gt; 
&lt;details&gt; 
 &lt;summary&gt;&lt;b&gt;Kubernetes&lt;/b&gt;&lt;/summary&gt; 
 &lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Install OpenTelemetry Operator
kubectl apply -f https://github.com/open-telemetry/opentelemetry-operator/releases/latest/download/opentelemetry-operator.yaml

# Configure auto-instrumentation
kubectl apply -f - &amp;lt;&amp;lt;EOF
apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
  name: my-instrumentation
spec:
  exporter:
    endpoint: http://monoscope:4317
  propagators:
    - tracecontext
    - baggage
EOF

# Annotate your deployments for auto-instrumentation
kubectl patch deployment my-app -p \
  &#39;{&quot;spec&quot;:{&quot;template&quot;:{&quot;metadata&quot;:{&quot;annotations&quot;:{&quot;instrumentation.opentelemetry.io/inject-java&quot;:&quot;my-instrumentation&quot;}}}}}&#39;
&lt;/code&gt;&lt;/pre&gt; 
&lt;/details&gt; 
&lt;br /&gt; 
&lt;h2&gt;Natural Language Queries&lt;/h2&gt; 
&lt;p&gt;Query your telemetry data in plain English:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&quot;Show me all errors in the payment service in the last hour&quot;&lt;/li&gt; 
 &lt;li&gt;&quot;What caused the spike in response time yesterday?&quot;&lt;/li&gt; 
 &lt;li&gt;&quot;Which endpoints have the highest p99 latency?&quot;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;br /&gt; 
&lt;h2&gt;AI Agents &amp;amp; Reports&lt;/h2&gt; 
&lt;p&gt;Create AI agents that monitor your systems on a schedule:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Scheduled analysis&lt;/strong&gt; — Agents run at intervals you define (hourly, daily, weekly)&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Anomaly detection&lt;/strong&gt; — Automatically surface unusual patterns in logs, metrics, and traces&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Email reports&lt;/strong&gt; — Receive summaries of important events and insights directly in your inbox&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Customizable focus&lt;/strong&gt; — Configure agents to watch specific services, error types, or metrics&lt;/li&gt; 
&lt;/ul&gt; 
&lt;br /&gt; 
&lt;h2&gt;Architecture&lt;/h2&gt; 
&lt;pre&gt;&lt;code class=&quot;language-mermaid&quot;&gt;graph LR
    A[Your Apps] --&amp;gt;|Logs/Metrics/Traces| B[Ingestion API]
    B --&amp;gt; C[TimeFusion Engine]
    C --&amp;gt; D[(S3 Storage)]
    D --&amp;gt; E[Query Engine]
    E --&amp;gt; F[Dashboards]
    D --&amp;gt; G[AI Agent Scheduler]
    G --&amp;gt;|LLM Analysis| H[Anomaly Detection]
    H --&amp;gt; I[Email Reports]
    H --&amp;gt; J[Alert Channels]
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Powered by TimeFusion&lt;/h3&gt; 
&lt;p&gt;Monoscope is built on &lt;a href=&quot;https://github.com/monoscope-tech/timefusion&quot;&gt;&lt;strong&gt;TimeFusion&lt;/strong&gt;&lt;/a&gt;, our open-source time-series database for observability workloads.&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt; 
   &lt;th&gt;&lt;/th&gt; 
   &lt;th&gt;&lt;/th&gt; 
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td&gt;🗄️ &lt;strong&gt;S3-native&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;Data lives in your S3 buckets—no vendor lock-in&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;🐘 &lt;strong&gt;PostgreSQL compatible&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;Use any Postgres client or driver&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;⚡ &lt;strong&gt;500K+ events/sec&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;Columnar storage with Apache Arrow&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;💵 &lt;strong&gt;Pay only for S3&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;No expensive proprietary storage fees&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;br /&gt; 
&lt;h2&gt;How It Compares&lt;/h2&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt; 
   &lt;th&gt;Feature&lt;/th&gt; 
   &lt;th&gt;Monoscope&lt;/th&gt; 
   &lt;th&gt;Datadog&lt;/th&gt; 
   &lt;th&gt;Elastic&lt;/th&gt; 
   &lt;th&gt;Prometheus&lt;/th&gt; 
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td&gt;S3/Object Storage&lt;/td&gt; 
   &lt;td&gt;✅ Native&lt;/td&gt; 
   &lt;td&gt;❌&lt;/td&gt; 
   &lt;td&gt;✅&lt;/td&gt; 
   &lt;td&gt;✅&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Natural Language Query&lt;/td&gt; 
   &lt;td&gt;✅&lt;/td&gt; 
   &lt;td&gt;❌&lt;/td&gt; 
   &lt;td&gt;❌&lt;/td&gt; 
   &lt;td&gt;❌&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;AI Agents &amp;amp; Reports&lt;/td&gt; 
   &lt;td&gt;✅ Built-in&lt;/td&gt; 
   &lt;td&gt;❌ Add-on&lt;/td&gt; 
   &lt;td&gt;❌&lt;/td&gt; 
   &lt;td&gt;❌&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Open Source&lt;/td&gt; 
   &lt;td&gt;✅ AGPL-3.0&lt;/td&gt; 
   &lt;td&gt;❌&lt;/td&gt; 
   &lt;td&gt;✅&lt;/td&gt; 
   &lt;td&gt;✅&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Self-hostable&lt;/td&gt; 
   &lt;td&gt;✅&lt;/td&gt; 
   &lt;td&gt;❌&lt;/td&gt; 
   &lt;td&gt;✅&lt;/td&gt; 
   &lt;td&gt;✅&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;br /&gt; 
&lt;h2&gt;Screenshots&lt;/h2&gt; 
&lt;h3&gt;Log Explorer - Unified View&lt;/h3&gt; 
&lt;p&gt;Logs and trace spans displayed together in context for complete observability.&lt;/p&gt; 
&lt;img src=&quot;https://github.com/user-attachments/assets/6175c23b-f3ac-450a-9ae3-4b86371f4f54&quot; alt=&quot;Log Explorer Main View&quot; width=&quot;100%&quot; /&gt; 
&lt;br /&gt; 
&lt;h3&gt;Trace Context Integration&lt;/h3&gt; 
&lt;p&gt;See detailed trace information alongside logs for debugging complex distributed systems.&lt;/p&gt; 
&lt;img src=&quot;https://github.com/user-attachments/assets/baf78e6f-2b75-4b6f-be56-94a0b3da9f31&quot; alt=&quot;Log Explorer with Trace Context&quot; width=&quot;100%&quot; /&gt; 
&lt;br /&gt; 
&lt;h3&gt;Dashboard Analytics&lt;/h3&gt; 
&lt;p&gt;Real-time metrics and performance monitoring with AI-powered insights.&lt;/p&gt; 
&lt;img src=&quot;https://github.com/user-attachments/assets/3dae136a-e627-4278-91a1-81c5af5f8cd6&quot; alt=&quot;Dashboard Analytics View&quot; width=&quot;100%&quot; /&gt; 
&lt;br /&gt; 
&lt;h2&gt;Trusted by Leading Companies&lt;/h2&gt; 
&lt;div align=&quot;center&quot;&gt; 
 &lt;table&gt; 
  &lt;tbody&gt;
   &lt;tr&gt; 
    &lt;td align=&quot;center&quot; width=&quot;120&quot; height=&quot;60&quot;&gt;&lt;img src=&quot;https://monoscope.tech/assets/img/customers/andela.svg?sanitize=true&quot; alt=&quot;Andela&quot; height=&quot;30&quot; /&gt;&lt;/td&gt; 
    &lt;td align=&quot;center&quot; width=&quot;120&quot; height=&quot;60&quot;&gt;&lt;img src=&quot;https://monoscope.tech/assets/img/customers/partna.svg?sanitize=true&quot; alt=&quot;Partna&quot; height=&quot;30&quot; /&gt;&lt;/td&gt; 
    &lt;td align=&quot;center&quot; width=&quot;120&quot; height=&quot;60&quot;&gt;&lt;img src=&quot;https://monoscope.tech/assets/img/customers/grovepay.svg?sanitize=true&quot; alt=&quot;GrovePay&quot; height=&quot;30&quot; /&gt;&lt;/td&gt; 
    &lt;td align=&quot;center&quot; width=&quot;120&quot; height=&quot;60&quot;&gt;&lt;img src=&quot;https://monoscope.tech/assets/img/customers/sameday.svg?sanitize=true&quot; alt=&quot;SameDay&quot; height=&quot;30&quot; /&gt;&lt;/td&gt; 
   &lt;/tr&gt; 
   &lt;tr&gt; 
    &lt;td align=&quot;center&quot; width=&quot;120&quot; height=&quot;60&quot;&gt;&lt;img src=&quot;https://monoscope.tech/assets/img/customers/platnova.png&quot; alt=&quot;Platnova&quot; height=&quot;30&quot; /&gt;&lt;/td&gt; 
    &lt;td align=&quot;center&quot; width=&quot;120&quot; height=&quot;60&quot;&gt;&lt;img src=&quot;https://monoscope.tech/assets/img/customers/payfonte.svg?sanitize=true&quot; alt=&quot;PayFonte&quot; height=&quot;30&quot; /&gt;&lt;/td&gt; 
    &lt;td align=&quot;center&quot; width=&quot;120&quot; height=&quot;60&quot;&gt;&lt;img src=&quot;https://monoscope.tech/assets/img/customers/thepeer.svg?sanitize=true&quot; alt=&quot;ThePeer&quot; height=&quot;30&quot; /&gt;&lt;/td&gt; 
    &lt;td align=&quot;center&quot; width=&quot;120&quot; height=&quot;60&quot;&gt;&lt;img src=&quot;https://monoscope.tech/assets/img/customers/blockradar-full.svg?sanitize=true&quot; alt=&quot;BlockRadar&quot; height=&quot;30&quot; /&gt;&lt;/td&gt; 
   &lt;/tr&gt; 
  &lt;/tbody&gt;
 &lt;/table&gt; 
&lt;/div&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&quot;Monoscope notifies us about any slight change on the system. Features that would cost us a lot more elsewhere.&quot; — &lt;strong&gt;Samuel Joseph, Woodcore&lt;/strong&gt;&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;br /&gt; 
&lt;h2&gt;Documentation&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/monoscope-tech/monoscope/master/docs/getting-started.md&quot;&gt;Getting Started Guide&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/monoscope-tech/monoscope/master/docs/cli.md&quot;&gt;CLI Reference&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/monoscope-tech/monoscope/master/docs/mcp.md&quot;&gt;MCP Server&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/monoscope-tech/monoscope/master/docs/configuration.md&quot;&gt;Configuration&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/monoscope-tech/monoscope/master/docs/kubernetes.md&quot;&gt;Kubernetes Guide&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/monoscope-tech/monoscope/master/docs/DEVELOPMENT.md&quot;&gt;Development Guide&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;br /&gt; 
&lt;h2&gt;Roadmap&lt;/h2&gt; 
&lt;ul class=&quot;task-list&quot;&gt; 
 &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; id=&quot;cbx_0&quot; checked=&quot;true&quot; disabled=&quot;true&quot; /&gt;&lt;label for=&quot;cbx_0&quot;&gt; Custom dashboards builder&lt;/label&gt;&lt;/li&gt; 
 &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; id=&quot;cbx_1&quot; disabled=&quot;true&quot; /&gt;&lt;label for=&quot;cbx_1&quot;&gt; More out-of-the-box dashboards&lt;/label&gt;&lt;/li&gt; 
 &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; id=&quot;cbx_2&quot; disabled=&quot;true&quot; /&gt;&lt;label for=&quot;cbx_2&quot;&gt; AIOps workflow builder&lt;/label&gt;&lt;/li&gt; 
 &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; id=&quot;cbx_3&quot; disabled=&quot;true&quot; /&gt;&lt;label for=&quot;cbx_3&quot;&gt; Full migration to TimeFusion storage engine&lt;/label&gt;&lt;/li&gt; 
 &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; id=&quot;cbx_4&quot; disabled=&quot;true&quot; /&gt;&lt;label for=&quot;cbx_4&quot;&gt; Metrics aggregation rules&lt;/label&gt;&lt;/li&gt; 
 &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; id=&quot;cbx_5&quot; disabled=&quot;true&quot; /&gt;&lt;label for=&quot;cbx_5&quot;&gt; Multi-tenant workspace support&lt;/label&gt;&lt;/li&gt; 
 &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; id=&quot;cbx_6&quot; disabled=&quot;true&quot; /&gt;&lt;label for=&quot;cbx_6&quot;&gt; More alert channel integrations&lt;/label&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;See our &lt;a href=&quot;https://github.com/monoscope-tech/monoscope/projects&quot;&gt;public roadmap&lt;/a&gt; for details and to vote on features.&lt;/p&gt; 
&lt;br /&gt; 
&lt;h2&gt;Community&lt;/h2&gt; 
&lt;p&gt;💬 &lt;a href=&quot;https://discord.gg/BSFCaUHxt4&quot;&gt;Discord&lt;/a&gt; • 🐛 &lt;a href=&quot;https://github.com/monoscope-tech/monoscope/issues&quot;&gt;Issues&lt;/a&gt; • 🐦 &lt;a href=&quot;https://x.com/monoscope-tech&quot;&gt;Twitter&lt;/a&gt;&lt;/p&gt; 
&lt;br /&gt; 
&lt;h2&gt;License&lt;/h2&gt; 
&lt;p&gt;AGPL-3.0. See &lt;a href=&quot;https://raw.githubusercontent.com/monoscope-tech/monoscope/master/LICENSE&quot;&gt;LICENSE&lt;/a&gt; for details.&lt;/p&gt; 
&lt;p&gt;For commercial licensing options, contact us at &lt;a href=&quot;mailto:hello@monoscope.tech&quot;&gt;hello@monoscope.tech&lt;/a&gt;.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;div align=&quot;center&quot;&gt; 
 &lt;a href=&quot;https://github.com/monoscope-tech/monoscope&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/monoscope-tech/monoscope?style=social&quot; alt=&quot;Star on GitHub&quot; /&gt;&lt;/a&gt; 
&lt;/div&gt;</description>
      
      <media:content url="https://opengraph.githubassets.com/02c597b5d19e099700d785aa20ddb357c1525f278085a4b8bb90a1e6fabbb039/monoscope-tech/monoscope" medium="image" />
      
    </item>
    
    <item>
      <title>jgm/pandoc</title>
      <link>https://github.com/jgm/pandoc</link>
      <description>&lt;p&gt;Universal markup converter&lt;/p&gt;&lt;hr&gt;&lt;h1&gt;Pandoc&lt;/h1&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/jgm/pandoc/releases&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/release/jgm/pandoc.svg?label=current+release&quot; alt=&quot;github
release&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://hackage.haskell.org/package/pandoc&quot;&gt;&lt;img src=&quot;https://img.shields.io/hackage/v/pandoc.svg?label=hackage&quot; alt=&quot;hackage
release&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://formulae.brew.sh/formula/pandoc&quot;&gt;&lt;img src=&quot;https://img.shields.io/homebrew/v/pandoc.svg?sanitize=true&quot; alt=&quot;homebrew&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://www.stackage.org/lts/package/pandoc&quot;&gt;&lt;img src=&quot;https://stackage.org/package/pandoc/badge/lts&quot; alt=&quot;stackage LTS
package&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://github.com/jgm/pandoc/actions&quot;&gt;&lt;img src=&quot;https://github.com/jgm/pandoc/workflows/CI%20tests/badge.svg?sanitize=true&quot; alt=&quot;CI
tests&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://www.gnu.org/licenses/gpl.html&quot;&gt;&lt;img src=&quot;https://img.shields.io/badge/license-GPLv2+-lightgray.svg?sanitize=true&quot; alt=&quot;license&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://groups.google.com/forum/#!forum/pandoc-discuss&quot;&gt;&lt;img src=&quot;https://img.shields.io/badge/pandoc-discuss-red.svg?style=social&quot; alt=&quot;pandoc-discuss on google
groups&quot; /&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;The universal markup converter&lt;/h2&gt; 
&lt;p&gt;Pandoc is a &lt;a href=&quot;https://haskell.org&quot;&gt;Haskell&lt;/a&gt; library for converting from one markup format to another, and a command-line tool that uses this library.&lt;/p&gt; 
&lt;p&gt;It can convert &lt;em&gt;from&lt;/em&gt;&lt;/p&gt; 
&lt;div id=&quot;input-formats&quot;&gt; 
 &lt;ul&gt; 
  &lt;li&gt;&lt;code&gt;asciidoc&lt;/code&gt; (&lt;a href=&quot;https://asciidoc.org/&quot;&gt;AsciiDoc&lt;/a&gt; markup)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;bibtex&lt;/code&gt; (&lt;a href=&quot;https://ctan.org/pkg/bibtex&quot;&gt;BibTeX&lt;/a&gt; bibliography)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;biblatex&lt;/code&gt; (&lt;a href=&quot;https://ctan.org/pkg/biblatex&quot;&gt;BibLaTeX&lt;/a&gt; bibliography)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;bits&lt;/code&gt; (&lt;a href=&quot;https://jats.nlm.nih.gov/extensions/bits/&quot;&gt;BITS&lt;/a&gt; XML, alias for &lt;code&gt;jats&lt;/code&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;commonmark&lt;/code&gt; (&lt;a href=&quot;https://commonmark.org&quot;&gt;CommonMark&lt;/a&gt; Markdown)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;commonmark_x&lt;/code&gt; (&lt;a href=&quot;https://commonmark.org&quot;&gt;CommonMark&lt;/a&gt; Markdown with extensions)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;creole&lt;/code&gt; (&lt;a href=&quot;http://www.wikicreole.org/wiki/Creole1.0&quot;&gt;Creole 1.0&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;csljson&lt;/code&gt; (&lt;a href=&quot;https://citeproc-js.readthedocs.io/en/latest/csl-json/markup.html&quot;&gt;CSL JSON&lt;/a&gt; bibliography)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;csv&lt;/code&gt; (&lt;a href=&quot;https://tools.ietf.org/html/rfc4180&quot;&gt;CSV&lt;/a&gt; table)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;tsv&lt;/code&gt; (&lt;a href=&quot;https://www.iana.org/assignments/media-types/text/tab-separated-values&quot;&gt;TSV&lt;/a&gt; table)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;djot&lt;/code&gt; (&lt;a href=&quot;https://djot.net&quot;&gt;Djot markup&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;docbook&lt;/code&gt; (&lt;a href=&quot;https://docbook.org&quot;&gt;DocBook&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;docx&lt;/code&gt; (&lt;a href=&quot;https://en.wikipedia.org/wiki/Office_Open_XML&quot;&gt;Word docx&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;dokuwiki&lt;/code&gt; (&lt;a href=&quot;https://www.dokuwiki.org/dokuwiki&quot;&gt;DokuWiki markup&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;endnotexml&lt;/code&gt; (&lt;a href=&quot;https://support.clarivate.com/Endnote/s/article/EndNote-XML-Document-Type-Definition&quot;&gt;EndNote XML bibliography&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;epub&lt;/code&gt; (&lt;a href=&quot;http://idpf.org/epub&quot;&gt;EPUB&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;fb2&lt;/code&gt; (&lt;a href=&quot;http://www.fictionbook.org/index.php/Eng:XML_Schema_Fictionbook_2.1&quot;&gt;FictionBook2&lt;/a&gt; e-book)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;gfm&lt;/code&gt; (&lt;a href=&quot;https://help.github.com/articles/github-flavored-markdown/&quot;&gt;GitHub-Flavored Markdown&lt;/a&gt;), or the deprecated and less accurate &lt;code&gt;markdown_github&lt;/code&gt;; use &lt;a href=&quot;https://pandoc.org/MANUAL.html#markdown-variants&quot;&gt;&lt;code&gt;markdown_github&lt;/code&gt;&lt;/a&gt; only if you need extensions not supported in &lt;a href=&quot;https://pandoc.org/MANUAL.html#markdown-variants&quot;&gt;&lt;code&gt;gfm&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;haddock&lt;/code&gt; (&lt;a href=&quot;https://www.haskell.org/haddock/doc/html/ch03s08.html&quot;&gt;Haddock markup&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;html&lt;/code&gt; (&lt;a href=&quot;https://www.w3.org/html/&quot;&gt;HTML&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;ipynb&lt;/code&gt; (&lt;a href=&quot;https://nbformat.readthedocs.io/en/latest/&quot;&gt;Jupyter notebook&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;jats&lt;/code&gt; (&lt;a href=&quot;https://jats.nlm.nih.gov&quot;&gt;JATS&lt;/a&gt; XML)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;jira&lt;/code&gt; (&lt;a href=&quot;https://jira.atlassian.com/secure/WikiRendererHelpAction.jspa?section=all&quot;&gt;Jira&lt;/a&gt;/Confluence wiki markup)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;json&lt;/code&gt; (JSON version of native AST)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;latex&lt;/code&gt; (&lt;a href=&quot;https://www.latex-project.org/&quot;&gt;LaTeX&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;markdown&lt;/code&gt; (&lt;a href=&quot;https://pandoc.org/MANUAL.html#pandocs-markdown&quot;&gt;Pandoc’s Markdown&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;markdown_mmd&lt;/code&gt; (&lt;a href=&quot;https://fletcherpenney.net/multimarkdown/&quot;&gt;MultiMarkdown&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;markdown_phpextra&lt;/code&gt; (&lt;a href=&quot;https://michelf.ca/projects/php-markdown/extra/&quot;&gt;PHP Markdown Extra&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;markdown_strict&lt;/code&gt; (original unextended &lt;a href=&quot;https://daringfireball.net/projects/markdown/&quot;&gt;Markdown&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;mediawiki&lt;/code&gt; (&lt;a href=&quot;https://www.mediawiki.org/wiki/Help:Formatting&quot;&gt;MediaWiki markup&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;man&lt;/code&gt; (&lt;a href=&quot;https://man.cx/groff_man(7)&quot;&gt;roff man&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;mdoc&lt;/code&gt; (&lt;a href=&quot;https://mandoc.bsd.lv/man/mdoc.7.html&quot;&gt;mdoc&lt;/a&gt; manual page markup)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;muse&lt;/code&gt; (&lt;a href=&quot;https://amusewiki.org/library/manual&quot;&gt;Muse&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;native&lt;/code&gt; (native Haskell)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;odt&lt;/code&gt; (&lt;a href=&quot;https://en.wikipedia.org/wiki/OpenDocument&quot;&gt;OpenDocument text document&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;opml&lt;/code&gt; (&lt;a href=&quot;https://opml.org/spec2.opml&quot;&gt;OPML&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;org&lt;/code&gt; (&lt;a href=&quot;https://orgmode.org&quot;&gt;Emacs Org mode&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;pod&lt;/code&gt; (Perl’s &lt;a href=&quot;https://perldoc.perl.org/perlpod&quot;&gt;Plain Old Documentation&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;pptx&lt;/code&gt; (&lt;a href=&quot;https://en.wikipedia.org/wiki/Microsoft_PowerPoint&quot;&gt;PowerPoint&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;ris&lt;/code&gt; (&lt;a href=&quot;https://en.wikipedia.org/wiki/RIS_(file_format)&quot;&gt;RIS&lt;/a&gt; bibliography)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;rtf&lt;/code&gt; (&lt;a href=&quot;https://en.wikipedia.org/wiki/Rich_Text_Format&quot;&gt;Rich Text Format&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;rst&lt;/code&gt; (&lt;a href=&quot;https://docutils.sourceforge.io/docs/ref/rst/introduction.html&quot;&gt;reStructuredText&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;t2t&lt;/code&gt; (&lt;a href=&quot;https://txt2tags.org&quot;&gt;txt2tags&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;textile&lt;/code&gt; (&lt;a href=&quot;https://textile-lang.com&quot;&gt;Textile&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;tikiwiki&lt;/code&gt; (&lt;a href=&quot;https://doc.tiki.org/Wiki-Syntax-Text#The_Markup_Language_Wiki-Syntax&quot;&gt;TikiWiki markup&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;twiki&lt;/code&gt; (&lt;a href=&quot;https://twiki.org/cgi-bin/view/TWiki/TextFormattingRules&quot;&gt;TWiki markup&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;typst&lt;/code&gt; (&lt;a href=&quot;https://typst.app&quot;&gt;typst&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;vimwiki&lt;/code&gt; (&lt;a href=&quot;https://vimwiki.github.io&quot;&gt;Vimwiki&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;xlsx&lt;/code&gt; (&lt;a href=&quot;https://en.wikipedia.org/wiki/Microsoft_Excel#File_formats&quot;&gt;Excel spreadsheet&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;xml&lt;/code&gt; (XML version of native AST)&lt;/li&gt; 
  &lt;li&gt;the path of a custom Lua reader, see &lt;a href=&quot;https://pandoc.org/MANUAL.html#custom-readers-and-writers&quot;&gt;Custom readers and writers&lt;/a&gt; below&lt;/li&gt; 
 &lt;/ul&gt; 
&lt;/div&gt; 
&lt;p&gt;It can convert &lt;em&gt;to&lt;/em&gt;&lt;/p&gt; 
&lt;div id=&quot;output-formats&quot;&gt; 
 &lt;ul&gt; 
  &lt;li&gt;&lt;code&gt;ansi&lt;/code&gt; (text with &lt;a href=&quot;https://en.wikipedia.org/wiki/ANSI_escape_code&quot;&gt;ANSI escape codes&lt;/a&gt;, for terminal viewing)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;asciidoc&lt;/code&gt; (modern &lt;a href=&quot;https://asciidoc.org/&quot;&gt;AsciiDoc&lt;/a&gt; as interpreted by &lt;a href=&quot;https://asciidoctor.org/&quot;&gt;AsciiDoctor&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;asciidoc_legacy&lt;/code&gt; (&lt;a href=&quot;https://asciidoc.org/&quot;&gt;AsciiDoc&lt;/a&gt; as interpreted by &lt;a href=&quot;https://github.com/asciidoc-py/asciidoc-py&quot;&gt;&lt;code&gt;asciidoc-py&lt;/code&gt;&lt;/a&gt;).&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;asciidoctor&lt;/code&gt; (deprecated synonym for &lt;code&gt;asciidoc&lt;/code&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;bbcode&lt;/code&gt; &lt;a href=&quot;https://www.bbcode.org/reference.php&quot;&gt;BBCode&lt;/a&gt;&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;bbcode_fluxbb&lt;/code&gt; &lt;a href=&quot;https://web.archive.org/web/20210623155046/https://fluxbb.org/forums/help.php#bbcode&quot;&gt;BBCode (FluxBB)&lt;/a&gt;&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;bbcode_phpbb&lt;/code&gt; &lt;a href=&quot;https://www.phpbb.com/community/help/bbcode&quot;&gt;BBCode (phpBB)&lt;/a&gt;&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;bbcode_steam&lt;/code&gt; &lt;a href=&quot;https://steamcommunity.com/comment/ForumTopic/formattinghelp&quot;&gt;BBCode (Steam)&lt;/a&gt;&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;bbcode_hubzilla&lt;/code&gt; &lt;a href=&quot;https://hubzilla.org/help/member/bbcode&quot;&gt;BBCode (Hubzilla)&lt;/a&gt;&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;bbcode_xenforo&lt;/code&gt; &lt;a href=&quot;https://www.xenfocus.com/community/help/bb-codes/&quot;&gt;BBCode (xenForo)&lt;/a&gt;&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;beamer&lt;/code&gt; (&lt;a href=&quot;https://ctan.org/pkg/beamer&quot;&gt;LaTeX beamer&lt;/a&gt; slide show)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;bibtex&lt;/code&gt; (&lt;a href=&quot;https://ctan.org/pkg/bibtex&quot;&gt;BibTeX&lt;/a&gt; bibliography)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;biblatex&lt;/code&gt; (&lt;a href=&quot;https://ctan.org/pkg/biblatex&quot;&gt;BibLaTeX&lt;/a&gt; bibliography)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;chunkedhtml&lt;/code&gt; (zip archive of multiple linked HTML files)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;commonmark&lt;/code&gt; (&lt;a href=&quot;https://commonmark.org&quot;&gt;CommonMark&lt;/a&gt; Markdown)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;commonmark_x&lt;/code&gt; (&lt;a href=&quot;https://commonmark.org&quot;&gt;CommonMark&lt;/a&gt; Markdown with extensions)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;context&lt;/code&gt; (&lt;a href=&quot;https://www.contextgarden.net/&quot;&gt;ConTeXt&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;csljson&lt;/code&gt; (&lt;a href=&quot;https://citeproc-js.readthedocs.io/en/latest/csl-json/markup.html&quot;&gt;CSL JSON&lt;/a&gt; bibliography)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;djot&lt;/code&gt; (&lt;a href=&quot;https://djot.net&quot;&gt;Djot markup&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;docbook&lt;/code&gt; or &lt;code&gt;docbook4&lt;/code&gt; (&lt;a href=&quot;https://docbook.org&quot;&gt;DocBook&lt;/a&gt; 4)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;docbook5&lt;/code&gt; (DocBook 5)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;docx&lt;/code&gt; (&lt;a href=&quot;https://en.wikipedia.org/wiki/Office_Open_XML&quot;&gt;Word docx&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;dokuwiki&lt;/code&gt; (&lt;a href=&quot;https://www.dokuwiki.org/dokuwiki&quot;&gt;DokuWiki markup&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;epub&lt;/code&gt; or &lt;code&gt;epub3&lt;/code&gt; (&lt;a href=&quot;http://idpf.org/epub&quot;&gt;EPUB&lt;/a&gt; v3 book)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;epub2&lt;/code&gt; (EPUB v2)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;fb2&lt;/code&gt; (&lt;a href=&quot;http://www.fictionbook.org/index.php/Eng:XML_Schema_Fictionbook_2.1&quot;&gt;FictionBook2&lt;/a&gt; e-book)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;gfm&lt;/code&gt; (&lt;a href=&quot;https://help.github.com/articles/github-flavored-markdown/&quot;&gt;GitHub-Flavored Markdown&lt;/a&gt;), or the deprecated and less accurate &lt;code&gt;markdown_github&lt;/code&gt;; use &lt;a href=&quot;https://pandoc.org/MANUAL.html#markdown-variants&quot;&gt;&lt;code&gt;markdown_github&lt;/code&gt;&lt;/a&gt; only if you need extensions not supported in &lt;a href=&quot;https://pandoc.org/MANUAL.html#markdown-variants&quot;&gt;&lt;code&gt;gfm&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;haddock&lt;/code&gt; (&lt;a href=&quot;https://www.haskell.org/haddock/doc/html/ch03s08.html&quot;&gt;Haddock markup&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;html&lt;/code&gt; or &lt;code&gt;html5&lt;/code&gt; (&lt;a href=&quot;https://www.w3.org/html/&quot;&gt;HTML&lt;/a&gt;, i.e.&amp;nbsp;&lt;a href=&quot;https://html.spec.whatwg.org/&quot;&gt;HTML5&lt;/a&gt;/XHTML &lt;a href=&quot;https://www.w3.org/TR/html-polyglot/&quot;&gt;polyglot markup&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;html4&lt;/code&gt; (&lt;a href=&quot;https://www.w3.org/TR/xhtml1/&quot;&gt;XHTML&lt;/a&gt; 1.0 Transitional)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;icml&lt;/code&gt; (&lt;a href=&quot;https://web.archive.org/web/20211006210211/https://wwwimages.adobe.com/www.adobe.com/content/dam/acom/en/devnet/indesign/sdk/cs6/idml/idml-cookbook.pdf&quot;&gt;InDesign ICML&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;ipynb&lt;/code&gt; (&lt;a href=&quot;https://nbformat.readthedocs.io/en/latest/&quot;&gt;Jupyter notebook&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;jats_archiving&lt;/code&gt; (&lt;a href=&quot;https://jats.nlm.nih.gov&quot;&gt;JATS&lt;/a&gt; XML, Archiving and Interchange Tag Set)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;jats_articleauthoring&lt;/code&gt; (&lt;a href=&quot;https://jats.nlm.nih.gov&quot;&gt;JATS&lt;/a&gt; XML, Article Authoring Tag Set)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;jats_publishing&lt;/code&gt; (&lt;a href=&quot;https://jats.nlm.nih.gov&quot;&gt;JATS&lt;/a&gt; XML, Journal Publishing Tag Set)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;jats&lt;/code&gt; (alias for &lt;code&gt;jats_archiving&lt;/code&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;jira&lt;/code&gt; (&lt;a href=&quot;https://jira.atlassian.com/secure/WikiRendererHelpAction.jspa?section=all&quot;&gt;Jira&lt;/a&gt;/Confluence wiki markup)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;json&lt;/code&gt; (JSON version of native AST)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;latex&lt;/code&gt; (&lt;a href=&quot;https://www.latex-project.org/&quot;&gt;LaTeX&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;man&lt;/code&gt; (&lt;a href=&quot;https://man.cx/groff_man(7)&quot;&gt;roff man&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;markdown&lt;/code&gt; (&lt;a href=&quot;https://pandoc.org/MANUAL.html#pandocs-markdown&quot;&gt;Pandoc’s Markdown&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;markdown_mmd&lt;/code&gt; (&lt;a href=&quot;https://fletcherpenney.net/multimarkdown/&quot;&gt;MultiMarkdown&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;markdown_phpextra&lt;/code&gt; (&lt;a href=&quot;https://michelf.ca/projects/php-markdown/extra/&quot;&gt;PHP Markdown Extra&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;markdown_strict&lt;/code&gt; (original unextended &lt;a href=&quot;https://daringfireball.net/projects/markdown/&quot;&gt;Markdown&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;markua&lt;/code&gt; (&lt;a href=&quot;https://leanpub.com/markua/read&quot;&gt;Markua&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;mediawiki&lt;/code&gt; (&lt;a href=&quot;https://www.mediawiki.org/wiki/Help:Formatting&quot;&gt;MediaWiki markup&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;ms&lt;/code&gt; (&lt;a href=&quot;https://man.cx/groff_ms(7)&quot;&gt;roff ms&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;muse&lt;/code&gt; (&lt;a href=&quot;https://amusewiki.org/library/manual&quot;&gt;Muse&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;native&lt;/code&gt; (native Haskell)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;odt&lt;/code&gt; (&lt;a href=&quot;https://en.wikipedia.org/wiki/OpenDocument&quot;&gt;OpenDocument text document&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;opml&lt;/code&gt; (&lt;a href=&quot;https://opml.org/spec2.opml&quot;&gt;OPML&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;opendocument&lt;/code&gt; (&lt;a href=&quot;https://www.oasis-open.org/2021/06/16/opendocument-v1-3-oasis-standard-published/&quot;&gt;OpenDocument XML&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;org&lt;/code&gt; (&lt;a href=&quot;https://orgmode.org&quot;&gt;Emacs Org mode&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;pdf&lt;/code&gt; (&lt;a href=&quot;https://www.adobe.com/pdf/&quot;&gt;PDF&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;plain&lt;/code&gt; (plain text)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;pptx&lt;/code&gt; (&lt;a href=&quot;https://en.wikipedia.org/wiki/Microsoft_PowerPoint&quot;&gt;PowerPoint&lt;/a&gt; slide show)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;rst&lt;/code&gt; (&lt;a href=&quot;https://docutils.sourceforge.io/docs/ref/rst/introduction.html&quot;&gt;reStructuredText&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;rtf&lt;/code&gt; (&lt;a href=&quot;https://en.wikipedia.org/wiki/Rich_Text_Format&quot;&gt;Rich Text Format&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;texinfo&lt;/code&gt; (&lt;a href=&quot;https://www.gnu.org/software/texinfo/&quot;&gt;GNU Texinfo&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;textile&lt;/code&gt; (&lt;a href=&quot;https://textile-lang.com&quot;&gt;Textile&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;slideous&lt;/code&gt; (&lt;a href=&quot;https://goessner.net/articles/slideous/&quot;&gt;Slideous&lt;/a&gt; HTML and JavaScript slide show)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;slidy&lt;/code&gt; (&lt;a href=&quot;https://www.w3.org/Talks/Tools/Slidy2/&quot;&gt;Slidy&lt;/a&gt; HTML and JavaScript slide show)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;dzslides&lt;/code&gt; (&lt;a href=&quot;https://paulrouget.com/dzslides/&quot;&gt;DZSlides&lt;/a&gt; HTML5 + JavaScript slide show)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;revealjs&lt;/code&gt; (&lt;a href=&quot;https://revealjs.com/&quot;&gt;reveal.js&lt;/a&gt; HTML5 + JavaScript slide show)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;s5&lt;/code&gt; (&lt;a href=&quot;https://meyerweb.com/eric/tools/s5/&quot;&gt;S5&lt;/a&gt; HTML and JavaScript slide show)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;tei&lt;/code&gt; (&lt;a href=&quot;https://github.com/TEIC/TEI-Simple&quot;&gt;TEI Simple&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;typst&lt;/code&gt; (&lt;a href=&quot;https://typst.app&quot;&gt;typst&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;vimdoc&lt;/code&gt; (&lt;a href=&quot;https://vimhelp.org/helphelp.txt.html#help-writing&quot;&gt;Vimdoc&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;xml&lt;/code&gt; (XML version of native AST)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;xwiki&lt;/code&gt; (&lt;a href=&quot;https://www.xwiki.org/xwiki/bin/view/Documentation/UserGuide/Features/XWikiSyntax/&quot;&gt;XWiki markup&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;zimwiki&lt;/code&gt; (&lt;a href=&quot;https://zim-wiki.org/manual/Help/Wiki_Syntax.html&quot;&gt;ZimWiki markup&lt;/a&gt;)&lt;/li&gt; 
  &lt;li&gt;the path of a custom Lua writer, see &lt;a href=&quot;https://pandoc.org/MANUAL.html#custom-readers-and-writers&quot;&gt;Custom readers and writers&lt;/a&gt; below&lt;/li&gt; 
 &lt;/ul&gt; 
&lt;/div&gt; 
&lt;p&gt;Pandoc can also produce PDF output via LaTeX, Groff ms, or HTML.&lt;/p&gt; 
&lt;p&gt;Pandoc’s enhanced version of Markdown includes syntax for tables, definition lists, metadata blocks, footnotes, citations, math, and much more. See the User’s Manual below under &lt;a href=&quot;https://pandoc.org/MANUAL.html#pandocs-markdown&quot;&gt;Pandoc’s Markdown&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;Pandoc has a modular design: it consists of a set of readers, which parse text in a given format and produce a native representation of the document (an &lt;em&gt;abstract syntax tree&lt;/em&gt; or AST), and a set of writers, which convert this native representation into a target format. Thus, adding an input or output format requires only adding a reader or writer. Users can also run custom pandoc filters to modify the intermediate AST (see the documentation for &lt;a href=&quot;https://pandoc.org/filters.html&quot;&gt;filters&lt;/a&gt; and &lt;a href=&quot;https://pandoc.org/lua-filters.html&quot;&gt;Lua filters&lt;/a&gt;).&lt;/p&gt; 
&lt;p&gt;Because pandoc’s intermediate representation of a document is less expressive than many of the formats it converts between, one should not expect perfect conversions between every format and every other. Pandoc attempts to preserve the structural elements of a document, but not formatting details such as margin size. And some document elements, such as complex tables, may not fit into pandoc’s simple document model. While conversions from pandoc’s Markdown to all formats aspire to be perfect, conversions from formats more expressive than pandoc’s Markdown can be expected to be lossy.&lt;/p&gt; 
&lt;h2&gt;Installing&lt;/h2&gt; 
&lt;p&gt;Here’s &lt;a href=&quot;https://raw.githubusercontent.com/jgm/pandoc/main/INSTALL.md&quot;&gt;how to install pandoc&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;Documentation&lt;/h2&gt; 
&lt;p&gt;Pandoc’s website contains a full &lt;a href=&quot;https://pandoc.org/MANUAL.html&quot;&gt;User’s Guide&lt;/a&gt;. It is also available &lt;a href=&quot;https://raw.githubusercontent.com/jgm/pandoc/main/MANUAL.txt&quot;&gt;here&lt;/a&gt; as pandoc-flavored Markdown. The website also contains some &lt;a href=&quot;https://pandoc.org/demos.html&quot;&gt;examples of the use of pandoc&lt;/a&gt;, a limited &lt;a href=&quot;https://pandoc.org/try&quot;&gt;online demo&lt;/a&gt;, and a &lt;a href=&quot;https://pandoc.org/app&quot;&gt;WebAssembly-based online demo&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;Contributing&lt;/h2&gt; 
&lt;p&gt;Pull requests, bug reports, and feature requests are welcome. Please make sure to read &lt;a href=&quot;https://raw.githubusercontent.com/jgm/pandoc/main/CONTRIBUTING.md&quot;&gt;the contributor guidelines&lt;/a&gt; before opening a new issue.&lt;/p&gt; 
&lt;h2&gt;License&lt;/h2&gt; 
&lt;p&gt;© 2006-2024 John MacFarlane (&lt;a href=&quot;mailto:jgm@berkeley.edu&quot;&gt;jgm@berkeley.edu&lt;/a&gt;). Released under the &lt;a href=&quot;https://www.gnu.org/licenses/old-licenses/gpl-2.0.html&quot; title=&quot;GNU General Public License&quot;&gt;GPL&lt;/a&gt;, version 2 or greater. This software carries no warranty of any kind. (See COPYRIGHT for full copyright and warranty notices.)&lt;/p&gt;</description>
      
      <media:content url="https://repository-images.githubusercontent.com/571770/2c9786ab-7e34-4eb1-8f90-6fb6dd64396a" medium="image" />
      
    </item>
    
    <item>
      <title>hadolint/hadolint</title>
      <link>https://github.com/hadolint/hadolint</link>
      <description>&lt;p&gt;Dockerfile linter, validate inline bash, written in Haskell&lt;/p&gt;&lt;hr&gt;&lt;h1&gt;Hadolint - Haskell Dockerfile Linter&lt;/h1&gt; 
&lt;p&gt;&lt;a href=&quot;https://tldrlegal.com/l/gpl-3.0&quot;&gt;&lt;img src=&quot;https://img.shields.io/badge/license-GPL--3-blue.svg?sanitize=true&quot; alt=&quot;GPL-3 licensed&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://github.com/hadolint/hadolint/releases/latest&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/v/release/hadolint/hadolint?logo=github&quot; alt=&quot;GitHub release&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://hackage.haskell.org/package/hadolint&quot;&gt;&lt;img src=&quot;https://img.shields.io/hackage/v/hadolint?logo=haskell&quot; alt=&quot;Hackage version&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://github.com/hadolint/hadolint/releases/latest&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/downloads/hadolint/hadolint/total?logo=github&quot; alt=&quot;GitHub downloads&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://hub.docker.com/r/hadolint/hadolint&quot;&gt;&lt;img src=&quot;https://img.shields.io/docker/pulls/hadolint/hadolint?logo=docker&quot; alt=&quot;Docker pulls&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://github.com/hadolint/hadolint/actions/workflows/haskell.yml&quot;&gt;&lt;img src=&quot;https://github.com/hadolint/hadolint/actions/workflows/haskell.yml/badge.svg?branch=master&quot; alt=&quot;Build Status&quot; /&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;img align=&quot;right&quot; alt=&quot;pipecat&quot; width=&quot;150&quot; src=&quot;https://hadolint.github.io/hadolint/img/cat_container.png&quot; /&gt;&lt;/p&gt; 
&lt;p&gt;A smarter Dockerfile linter that helps you build &lt;a href=&quot;https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices&quot;&gt;best practice&lt;/a&gt; Docker images. The linter parses the Dockerfile into an AST and performs rules on top of the AST. It stands on the shoulders of &lt;a href=&quot;https://github.com/koalaman/shellcheck&quot;&gt;ShellCheck&lt;/a&gt; to lint the Bash code inside &lt;code&gt;RUN&lt;/code&gt; instructions.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://hadolint.github.io/hadolint&quot;&gt;🌐 &lt;strong&gt;Check the online version on hadolint.github.io/hadolint&lt;/strong&gt;&lt;/a&gt; &lt;a href=&quot;https://hadolint.github.io/hadolint&quot;&gt;&lt;img src=&quot;https://raw.githubusercontent.com/hadolint/hadolint/master/screenshot.png&quot; alt=&quot;Screenshot&quot; /&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Table of Contents&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/hadolint/hadolint/master/#how-to-use&quot;&gt;How to use&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/hadolint/hadolint/master/#install&quot;&gt;Install&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/hadolint/hadolint/master/#cli&quot;&gt;CLI&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/hadolint/hadolint/master/#configure&quot;&gt;Configure&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/hadolint/hadolint/master/#non-posix-shells&quot;&gt;Non-Posix Shells&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/hadolint/hadolint/master/#ignoring-rules&quot;&gt;Ignoring Rules&lt;/a&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/hadolint/hadolint/master/#inline-ignores&quot;&gt;Inline ignores&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/hadolint/hadolint/master/#global-ignores&quot;&gt;Global ignores&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/hadolint/hadolint/master/#linting-labels&quot;&gt;Linting Labels&lt;/a&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/hadolint/hadolint/master/#note-on-dealing-with-variables-in-labels&quot;&gt;Note on dealing with variables in labels&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/hadolint/hadolint/master/#integrations&quot;&gt;Integrations&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/hadolint/hadolint/master/#rules&quot;&gt;Rules&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/hadolint/hadolint/master/#develop&quot;&gt;Develop&lt;/a&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/hadolint/hadolint/master/#setup&quot;&gt;Setup&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/hadolint/hadolint/master/#repl&quot;&gt;REPL&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/hadolint/hadolint/master/#tests&quot;&gt;Tests&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/hadolint/hadolint/master/#ast&quot;&gt;AST&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/hadolint/hadolint/master/#building-against-custom-libraries&quot;&gt;Building against custom libraries&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/hadolint/hadolint/master/#alternatives&quot;&gt;Alternatives&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;How to use&lt;/h2&gt; 
&lt;p&gt;You can run &lt;code&gt;hadolint&lt;/code&gt; locally to lint your Dockerfile.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;hadolint &amp;lt;Dockerfile&amp;gt;
hadolint --ignore DL3003 --ignore DL3006 &amp;lt;Dockerfile&amp;gt; # exclude specific rules
hadolint --trusted-registry my-company.com:500 &amp;lt;Dockerfile&amp;gt; # Warn when using untrusted FROM images
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Docker comes to the rescue, providing an easy way how to run &lt;code&gt;hadolint&lt;/code&gt; on most platforms. Just pipe your &lt;code&gt;Dockerfile&lt;/code&gt; to &lt;code&gt;docker run&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;docker run --rm -i hadolint/hadolint &amp;lt; Dockerfile
# OR
docker run --rm -i ghcr.io/hadolint/hadolint &amp;lt; Dockerfile
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;or using &lt;a href=&quot;https://podman.io/&quot;&gt;Podman&lt;/a&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;podman run --rm -i docker.io/hadolint/hadolint &amp;lt; Dockerfile
# OR
podman run --rm -i ghcr.io/hadolint/hadolint &amp;lt; Dockerfile
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;or using Windows PowerShell:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;cat .\Dockerfile | docker run --rm -i hadolint/hadolint
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Install&lt;/h2&gt; 
&lt;p&gt;You can download prebuilt binaries for OSX, Windows and Linux from the latest &lt;a href=&quot;https://github.com/hadolint/hadolint/releases/latest&quot;&gt;release page&lt;/a&gt;. However, if this does not work for you, please fall back to container (Docker), &lt;code&gt;brew&lt;/code&gt; or source installation.&lt;/p&gt; 
&lt;p&gt;On OSX, you can use &lt;a href=&quot;https://brew.sh/&quot;&gt;brew&lt;/a&gt; to install &lt;code&gt;hadolint&lt;/code&gt;.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;brew install hadolint
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;On Windows, you can use &lt;a href=&quot;https://github.com/lukesampson/scoop&quot;&gt;scoop&lt;/a&gt; to install &lt;code&gt;hadolint&lt;/code&gt;.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-batch&quot;&gt;scoop install hadolint
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;On distributions that have &lt;code&gt;nix&lt;/code&gt; installed, you can use the &lt;code&gt;hadolint&lt;/code&gt; package to run ad-hoc shells or permanently install &lt;code&gt;hadolint&lt;/code&gt; into your environment.&lt;/p&gt; 
&lt;p&gt;As mentioned earlier, &lt;code&gt;hadolint&lt;/code&gt; is available as a container image:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;docker pull hadolint/hadolint
# OR
docker pull ghcr.io/hadolint/hadolint
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;If you need a container with shell access, use the Debian or Alpine variants:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;docker pull hadolint/hadolint:latest-debian
# OR
docker pull hadolint/hadolint:latest-alpine
# OR
docker pull ghcr.io/hadolint/hadolint:latest-debian
# OR
docker pull ghcr.io/hadolint/hadolint:latest-alpine
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;You can also build &lt;code&gt;hadolint&lt;/code&gt; locally. You need &lt;a href=&quot;https://www.haskell.org/downloads/&quot;&gt;Haskell&lt;/a&gt; and the &lt;a href=&quot;https://www.haskell.org/cabal/&quot;&gt;cabal&lt;/a&gt; build tool to build the binary.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git clone https://github.com/hadolint/hadolint \
  &amp;amp;&amp;amp; cd hadolint \
  &amp;amp;&amp;amp; cabal configure \
  &amp;amp;&amp;amp; cabal build \
  &amp;amp;&amp;amp; cabal install
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;If you want the &lt;a href=&quot;https://github.com/michaellzc/vscode-hadolint&quot;&gt;VS Code Hadolint&lt;/a&gt; extension to use Hadolint in a container, you can use the following &lt;a href=&quot;https://github.com/hadolint/hadolint/issues/691#issuecomment-932116329&quot;&gt;wrapper script&lt;/a&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;#!/bin/bash
dockerfile=&quot;$1&quot;
shift
docker run --rm -i hadolint/hadolint hadolint &quot;$@&quot; - &amp;lt; &quot;$dockerfile&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;CLI&lt;/h2&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;hadolint --help
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;hadolint - Dockerfile Linter written in Haskell

Usage: hadolint [-v|--version] [-c|--config FILENAME] [DOCKERFILE...]
                [--file-path-in-report FILEPATHINREPORT] [--no-fail]
                [--no-color] [-V|--verbose] [-f|--format ARG] [--error RULECODE]
                [--warning RULECODE] [--info RULECODE] [--style RULECODE]
                [--ignore RULECODE]
                [--trusted-registry REGISTRY (e.g. docker.io)]
                [--require-label LABELSCHEMA (e.g. maintainer:text)]
                [--strict-labels] [--disable-ignore-pragma]
                [-t|--failure-threshold THRESHOLD]
  Lint Dockerfile for errors and best practices

Available options:
  -h,--help                Show this help text
  -v,--version             Show version
  -c,--config FILENAME     Path to the configuration file
  --file-path-in-report FILEPATHINREPORT
                           The file path referenced in the generated report.
                           This only applies for the &#39;checkstyle&#39;, &#39;codeclimate&#39;,
                           &#39;sonarqube&#39; and &#39;gitlab_codeclimate&#39; formats and is
                           useful when running Hadolint with Docker to set the
                           correct file path.
  --no-fail                Don&#39;t exit with a failure status code when any rule
                           is violated
  --no-color               Don&#39;t colorize output
  -V,--verbose             Enables verbose logging of hadolint&#39;s output to
                           stderr
  -f,--format ARG          The output format for the results [tty | json |
                           checkstyle | codeclimate | gitlab_codeclimate | gnu |
                           codacy | sonarqube | sarif] (default: tty)
  --error RULECODE         Make the rule `RULECODE` have the level `error`
  --warning RULECODE       Make the rule `RULECODE` have the level `warning`
  --info RULECODE          Make the rule `RULECODE` have the level `info`
  --style RULECODE         Make the rule `RULECODE` have the level `style`
  --ignore RULECODE        A rule to ignore. If present, the ignore list in the
                           config file is ignored
  --trusted-registry REGISTRY (e.g. docker.io)
                           A docker registry to allow to appear in FROM
                           instructions
  --require-label LABELSCHEMA (e.g. maintainer:text)
                           The option --require-label=label:format makes
                           Hadolint check that the label `label` conforms to
                           format requirement `format`
  --strict-labels          Do not permit labels other than specified in
                           `label-schema`
  --disable-ignore-pragma  Disable inline ignore pragmas `# hadolint
                           ignore=DLxxxx`
  -t,--failure-threshold THRESHOLD
                           Exit with failure code only when rules with a
                           severity equal to or above THRESHOLD are violated.
                           Accepted values: [error | warning | info | style |
                           ignore | none] (default: info)
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Configure&lt;/h2&gt; 
&lt;p&gt;Configuration files can be used globally or per project. Hadolint looks for configuration files in the following locations or their platform specific equivalents in this order and uses the first one exclusively:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;$PWD/.hadolint.yaml&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;$XDG_CONFIG_HOME/hadolint.yaml&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;$HOME/.config/hadolint.yaml&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;$HOME/.hadolint/hadolint.yaml or $HOME/hadolint/config.yaml&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;$HOME/.hadolint.yaml&lt;/code&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;In windows, the &lt;code&gt;%LOCALAPPDATA%&lt;/code&gt; environment variable is used instead of &lt;code&gt;XDG_CONFIG_HOME&lt;/code&gt;. Config files can have either &lt;code&gt;yaml&lt;/code&gt; or &lt;code&gt;yml&lt;/code&gt; extensions.&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;hadolint&lt;/code&gt; full &lt;code&gt;yaml&lt;/code&gt; config file schema&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;failure-threshold: string               # name of threshold level (error | warning | info | style | ignore | none)
format: string                          # Output format (tty | json | checkstyle | codeclimate | gitlab_codeclimate | gnu | codacy)
ignored: [string]                       # list of rules
label-schema:                           # See Linting Labels below for specific label-schema details
  author: string                        # Your name
  contact: string                       # email address
  created: timestamp                    # rfc3339 datetime
  version: string                       # semver
  documentation: string                 # url
  git-revision: string                  # hash
  license: string                       # spdx
no-color: boolean                       # true | false
no-fail: boolean                        # true | false
override:
  error: [string]                       # list of rules
  warning: [string]                     # list of rules
  info: [string]                        # list of rules
  style: [string]                       # list of rules
strict-labels: boolean                  # true | false
disable-ignore-pragma: boolean          # true | false
trustedRegistries: string | [string]    # registry or list of registries
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;code&gt;hadolint&lt;/code&gt; supports specifying the ignored rules using a configuration file. The configuration file should be in &lt;code&gt;yaml&lt;/code&gt; format. This is one valid configuration file as an example:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;ignored:
  - DL3000
  - SC1010
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Additionally, &lt;code&gt;hadolint&lt;/code&gt; can warn you when images from untrusted repositories are being used in Dockerfiles, you can append the &lt;code&gt;trustedRegistries&lt;/code&gt; keys to the configuration file, as shown below:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;ignored:
  - DL3000
  - SC1010

trustedRegistries:
  - docker.io
  - my-company.com:5000
  - &quot;*.gcr.io&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;If you want to override the severity of specific rules, you can do that too:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;override:
  error:
    - DL3001
    - DL3002
  warning:
    - DL3042
    - DL3033
  info:
    - DL3032
  style:
    - DL3015
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;code&gt;failure-threshold&lt;/code&gt; Exit with failure code only when rules with a severity above THRESHOLD are violated (Available in v2.6.0+)&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;failure-threshold: info
override:
  warning:
    - DL3042
    - DL3033
  info:
    - DL3032
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Additionally, you can pass a custom configuration file in the command line with the &lt;code&gt;--config&lt;/code&gt; option&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;hadolint --config /path/to/config.yaml Dockerfile
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;To pass a custom configuration file (using relative or absolute path) to a container, use the following command:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;docker run --rm -i -v /your/path/to/hadolint.yaml:/.config/hadolint.yaml hadolint/hadolint &amp;lt; Dockerfile
# OR
docker run --rm -i -v /your/path/to/hadolint.yaml:/.config/hadolint.yaml ghcr.io/hadolint/hadolint &amp;lt; Dockerfile
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;In addition to config files, Hadolint can be configured with environment variables.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;NO_COLOR=1                               # Set or unset. See https://no-color.org
HADOLINT_NOFAIL=1                        # Truthy value e.g. 1, true or yes
HADOLINT_VERBOSE=1                       # Truthy value e.g. 1, true or yes
HADOLINT_FORMAT=json                     # Output format (tty | json | checkstyle | codeclimate | gitlab_codeclimate | gnu | codacy | sarif )
HADOLINT_FAILURE_THRESHOLD=info          # threshold level (error | warning | info | style | ignore | none)
HADOLINT_OVERRIDE_ERROR=DL3010,DL3020    # comma separated list of rule codes
HADOLINT_OVERRIDE_WARNING=DL3010,DL3020  # comma separated list of rule codes
HADOLINT_OVERRIDE_INFO=DL3010,DL3020     # comma separated list of rule codes
HADOLINT_OVERRIDE_STYLE=DL3010,DL3020    # comma separated list of rule codes
HADOLINT_IGNORE=DL3010,DL3020            # comma separated list of rule codes
HADOLINT_STRICT_LABELS=1                 # Truthy value e.g. 1, true or yes
HADOLINT_DISABLE_IGNORE_PRAGMA=1         # Truthy value e.g. 1, true or yes
HADOLINT_TRUSTED_REGISTRIES=docker.io    # comma separated list of registry urls
HADOLINT_REQUIRE_LABELS=maintainer:text  # comma separated list of label schema items
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Non-Posix Shells&lt;/h2&gt; 
&lt;p&gt;When using base images with non-posix shells as default (e.g. Windows based images) a special pragma &lt;code&gt;hadolint shell&lt;/code&gt; can specify which shell the base image uses, so that Hadolint can automatically ignore all shell-specific rules.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-Dockerfile&quot;&gt;FROM mcr.microsoft.com/windows/servercore:ltsc2022
# hadolint shell=powershell
RUN Get-Process notepad | Stop-Process
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Ignoring Rules&lt;/h2&gt; 
&lt;h3&gt;Inline ignores&lt;/h3&gt; 
&lt;p&gt;It is also possible to ignore rules by adding a special comment directly above the Dockerfile statement for which you want to make an exception for. Such comments look like &lt;code&gt;# hadolint ignore=DL3001,SC1081&lt;/code&gt;. For example:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-dockerfile&quot;&gt;# hadolint ignore=DL3006
FROM ubuntu

# hadolint ignore=DL3003,SC1035 # We accept these issues, because ...
RUN cd /tmp &amp;amp;&amp;amp; echo &quot;hello!&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The comment &quot;inline ignores&quot; applies only to the statement following it.&lt;/p&gt; 
&lt;p&gt;Comments are allowed after the &lt;code&gt;ignore=...&lt;/code&gt;, you need an extra &lt;code&gt;#&lt;/code&gt;&lt;/p&gt; 
&lt;h3&gt;Global ignores&lt;/h3&gt; 
&lt;p&gt;Rules can also be ignored on a per-file basis using the global ignore pragma. It works just like inline ignores, except that it applies to the whole file instead of just the next line.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-dockerfile&quot;&gt;# hadolint global ignore=DL3003,DL3006,SC1035 # We accept these issues, because ...
FROM ubuntu

RUN cd /tmp &amp;amp;&amp;amp; echo &quot;foo&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Linting Labels&lt;/h2&gt; 
&lt;p&gt;Hadolint is able to check if specific labels are present and conform to a predefined label schema. First, a label schema must be defined either via the command line:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;hadolint --require-label author:text --require-label version:semver Dockerfile
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;or via the config file:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;label-schema:
  author: text
  contact: email
  created: rfc3339
  version: semver
  documentation: url
  git-revision: hash
  license: spdx
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The value of a label can be either of &lt;code&gt;text&lt;/code&gt;, &lt;code&gt;url&lt;/code&gt;, &lt;code&gt;semver&lt;/code&gt;, &lt;code&gt;hash&lt;/code&gt; or &lt;code&gt;rfc3339&lt;/code&gt;:&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt; 
   &lt;th style=&quot;text-align:left&quot;&gt;Schema&lt;/th&gt; 
   &lt;th style=&quot;text-align:left&quot;&gt;Description&lt;/th&gt; 
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;text&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Anything&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;rfc3339&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;A time, formatted according to &lt;a href=&quot;https://www.ietf.org/rfc/rfc3339.txt&quot;&gt;RFC 3339&lt;/a&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;semver&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;A &lt;a href=&quot;https://semver.org/&quot;&gt;semantic version&lt;/a&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;url&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;A URI as described in &lt;a href=&quot;https://www.ietf.org/rfc/rfc3986.txt&quot;&gt;RFC 3986&lt;/a&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;hash&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Either a short or a long &lt;a href=&quot;https://git-scm.com/book/en/v2/Git-Tools-Revision-Selection&quot;&gt;Git hash&lt;/a&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;spdx&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;An &lt;a href=&quot;https://spdx.org/licenses/&quot;&gt;SPDX license identifier&lt;/a&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;email&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;An email address conforming to &lt;a href=&quot;https://www.ietf.org/rfc/rfc5322.txt&quot;&gt;RFC 5322&lt;/a&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;By default, Hadolint ignores any label that is not specified in the label schema. To warn against such additional labels, turn on strict labels, using the command line:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;hadolint --strict-labels --require-label version:semver Dockerfile
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;or the config file:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;strict-labels: true
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;When strict labels is enabled, but no label schema is specified, &lt;code&gt;hadolint&lt;/code&gt; will warn if any label is present.&lt;/p&gt; 
&lt;h3&gt;Note on dealing with variables in labels&lt;/h3&gt; 
&lt;p&gt;It is a common pattern to fill the value of a label not statically, but rather dynamically at build time by using a variable:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-dockerfile&quot;&gt;FROM debian:buster
ARG VERSION=&quot;du-jour&quot;
LABEL version=&quot;${VERSION}&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;To allow this, the label schema must specify &lt;code&gt;text&lt;/code&gt; as value for that label:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;label-schema:
  version: text
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Integrations&lt;/h2&gt; 
&lt;p&gt;To get most of &lt;code&gt;hadolint&lt;/code&gt;, it is useful to integrate it as a check in your CI or into your editor, or as a pre-commit hook, to lint your &lt;code&gt;Dockerfile&lt;/code&gt; as you write it. See our &lt;a href=&quot;https://raw.githubusercontent.com/hadolint/hadolint/master/docs/INTEGRATION.md&quot;&gt;Integration&lt;/a&gt; docs.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/hadolint/hadolint/master/docs/INTEGRATION.md#code-review&quot;&gt;Code Review Platform Integrations&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/hadolint/hadolint/master/docs/INTEGRATION.md#continuous-integration&quot;&gt;Continuous Integrations&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/hadolint/hadolint/master/docs/INTEGRATION.md#editors&quot;&gt;Editor Integrations&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/hadolint/hadolint/master/docs/INTEGRATION.md#version-control&quot;&gt;Version Control Integrations&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Rules&lt;/h2&gt; 
&lt;p&gt;An incomplete list of implemented rules. Click on the error code to get more detailed information.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;Rules with the prefix &lt;code&gt;DL&lt;/code&gt; are from &lt;code&gt;hadolint&lt;/code&gt;. Have a look at &lt;code&gt;Rules.hs&lt;/code&gt; to find the implementation of the rules.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Rules with the &lt;code&gt;SC&lt;/code&gt; prefix are from &lt;strong&gt;ShellCheck&lt;/strong&gt; (only the most common rules are listed, there are dozens more).&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Please &lt;a href=&quot;https://github.com/hadolint/hadolint/issues/new&quot;&gt;create an issue&lt;/a&gt; if you have an idea for a good rule.&lt;/p&gt; 
&lt;!--lint disable maximum-line-length--&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt; 
   &lt;th style=&quot;text-align:left&quot;&gt;Rule&lt;/th&gt; 
   &lt;th style=&quot;text-align:left&quot;&gt;Default Severity&lt;/th&gt; 
   &lt;th style=&quot;text-align:left&quot;&gt;Description&lt;/th&gt; 
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL1001&quot;&gt;DL1001&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Ignore&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Please refrain from using inline ignore pragmas &lt;code&gt;# hadolint ignore=DLxxxx&lt;/code&gt;.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3000&quot;&gt;DL3000&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Error&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Use absolute WORKDIR.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3001&quot;&gt;DL3001&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Info&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;For some bash commands it makes no sense running them in a Docker container like ssh, vim, shutdown, service, ps, free, top, kill, mount, ifconfig.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3002&quot;&gt;DL3002&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Last user should not be root.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3003&quot;&gt;DL3003&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Use WORKDIR to switch to a directory.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3004&quot;&gt;DL3004&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Error&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Do not use sudo as it leads to unpredictable behavior. Use a tool like gosu to enforce root.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3006&quot;&gt;DL3006&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Always tag the version of an image explicitly.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3007&quot;&gt;DL3007&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Using latest is prone to errors if the image will ever update. Pin the version explicitly to a release tag.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3008&quot;&gt;DL3008&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Pin versions in &lt;code&gt;apt-get install&lt;/code&gt;.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3009&quot;&gt;DL3009&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Info&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Delete the apt-get lists after installing something.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3010&quot;&gt;DL3010&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Info&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Use ADD for extracting archives into an image.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3011&quot;&gt;DL3011&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Error&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Valid UNIX ports range from 0 to 65535.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3012&quot;&gt;DL3012&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Error&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Multiple &lt;code&gt;HEALTHCHECK&lt;/code&gt; instructions.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3013&quot;&gt;DL3013&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Pin versions in pip.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3014&quot;&gt;DL3014&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Use the &lt;code&gt;-y&lt;/code&gt; switch.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3015&quot;&gt;DL3015&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Info&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Avoid additional packages by specifying &lt;code&gt;--no-install-recommends&lt;/code&gt;.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3016&quot;&gt;DL3016&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Pin versions in &lt;code&gt;npm&lt;/code&gt;.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3018&quot;&gt;DL3018&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Pin versions in &lt;code&gt;apk add&lt;/code&gt;. Instead of &lt;code&gt;apk add &amp;lt;package&amp;gt;&lt;/code&gt; use &lt;code&gt;apk add &amp;lt;package&amp;gt;=&amp;lt;version&amp;gt;&lt;/code&gt;.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3019&quot;&gt;DL3019&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Info&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Use the &lt;code&gt;--no-cache&lt;/code&gt; switch to avoid the need to use &lt;code&gt;--update&lt;/code&gt; and remove &lt;code&gt;/var/cache/apk/*&lt;/code&gt; when done installing packages.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3020&quot;&gt;DL3020&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Error&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Use &lt;code&gt;COPY&lt;/code&gt; instead of &lt;code&gt;ADD&lt;/code&gt; for files and folders.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3021&quot;&gt;DL3021&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Error&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;COPY&lt;/code&gt; with more than 2 arguments requires the last argument to end with &lt;code&gt;/&lt;/code&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3022&quot;&gt;DL3022&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;COPY --from&lt;/code&gt; should reference a previously defined &lt;code&gt;FROM&lt;/code&gt; alias&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3023&quot;&gt;DL3023&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Error&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;COPY --from&lt;/code&gt; cannot reference its own &lt;code&gt;FROM&lt;/code&gt; alias&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3024&quot;&gt;DL3024&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Error&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;FROM&lt;/code&gt; aliases (stage names) must be unique&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3025&quot;&gt;DL3025&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Use arguments JSON notation for CMD and ENTRYPOINT arguments&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3026&quot;&gt;DL3026&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Error&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Use only an allowed registry in the &lt;code&gt;FROM image&lt;/code&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3027&quot;&gt;DL3027&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Do not use &lt;code&gt;apt&lt;/code&gt; as it is meant to be an end-user tool, use &lt;code&gt;apt-get&lt;/code&gt; or &lt;code&gt;apt-cache&lt;/code&gt; instead&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3028&quot;&gt;DL3028&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Pin versions in gem install. Instead of &lt;code&gt;gem install &amp;lt;gem&amp;gt;&lt;/code&gt; use &lt;code&gt;gem install &amp;lt;gem&amp;gt;:&amp;lt;version&amp;gt;&lt;/code&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3029&quot;&gt;DL3029&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Do not use --platform flag with FROM.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3030&quot;&gt;DL3030&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Use the &lt;code&gt;-y&lt;/code&gt; switch to avoid manual input &lt;code&gt;yum install -y &amp;lt;package&amp;gt;&lt;/code&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3032&quot;&gt;DL3032&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;yum clean all&lt;/code&gt; missing after yum command.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3033&quot;&gt;DL3033&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Specify version with &lt;code&gt;yum install -y &amp;lt;package&amp;gt;-&amp;lt;version&amp;gt;&lt;/code&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3034&quot;&gt;DL3034&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Non-interactive switch missing from &lt;code&gt;zypper&lt;/code&gt; command: &lt;code&gt;zypper install -y&lt;/code&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3035&quot;&gt;DL3035&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Do not use &lt;code&gt;zypper dist-upgrade&lt;/code&gt;.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3036&quot;&gt;DL3036&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;zypper clean&lt;/code&gt; missing after zypper use.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3037&quot;&gt;DL3037&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Specify version with &lt;code&gt;zypper install -y &amp;lt;package&amp;gt;[=]&amp;lt;version&amp;gt;&lt;/code&gt;.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3038&quot;&gt;DL3038&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Use the &lt;code&gt;-y&lt;/code&gt; switch to avoid manual input &lt;code&gt;dnf install -y &amp;lt;package&amp;gt;&lt;/code&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3040&quot;&gt;DL3040&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;dnf clean all&lt;/code&gt; missing after dnf command.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3041&quot;&gt;DL3041&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Specify version with &lt;code&gt;dnf install -y &amp;lt;package&amp;gt;-&amp;lt;version&amp;gt;&lt;/code&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3042&quot;&gt;DL3042&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Avoid cache directory with &lt;code&gt;pip install --no-cache-dir &amp;lt;package&amp;gt;&lt;/code&gt;.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3043&quot;&gt;DL3043&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Error&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;ONBUILD&lt;/code&gt;, &lt;code&gt;FROM&lt;/code&gt; or &lt;code&gt;MAINTAINER&lt;/code&gt; triggered from within &lt;code&gt;ONBUILD&lt;/code&gt; instruction.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3044&quot;&gt;DL3044&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Error&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Do not refer to an environment variable within the same &lt;code&gt;ENV&lt;/code&gt; statement where it is defined.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3045&quot;&gt;DL3045&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;COPY&lt;/code&gt; to a relative destination without &lt;code&gt;WORKDIR&lt;/code&gt; set.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3046&quot;&gt;DL3046&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;useradd&lt;/code&gt; without flag &lt;code&gt;-l&lt;/code&gt; and high UID will result in excessively large Image.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3047&quot;&gt;DL3047&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Info&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;wget&lt;/code&gt; without flag &lt;code&gt;--progress&lt;/code&gt; will result in excessively bloated build logs when downloading larger files.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3048&quot;&gt;DL3048&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Style&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Invalid Label Key&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3049&quot;&gt;DL3049&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Info&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Label &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; is missing.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3050&quot;&gt;DL3050&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Info&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Superfluous label(s) present.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3051&quot;&gt;DL3051&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Label &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; is empty.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3052&quot;&gt;DL3052&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Label &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; is not a valid URL.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3053&quot;&gt;DL3053&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Label &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; is not a valid time format - must conform to RFC3339.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3054&quot;&gt;DL3054&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Label &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; is not a valid SPDX license identifier.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3055&quot;&gt;DL3055&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Label &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; is not a valid git hash.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3056&quot;&gt;DL3056&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Label &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; does not conform to semantic versioning.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3057&quot;&gt;DL3057&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Ignore&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;HEALTHCHECK&lt;/code&gt; instruction missing.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3058&quot;&gt;DL3058&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Label &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; is not a valid email format - must conform to RFC5322.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3059&quot;&gt;DL3059&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Info&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Multiple consecutive &lt;code&gt;RUN&lt;/code&gt; instructions. Consider consolidation.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3060&quot;&gt;DL3060&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Info&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;yarn cache clean&lt;/code&gt; missing after &lt;code&gt;yarn install&lt;/code&gt; was run.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3061&quot;&gt;DL3061&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Error&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Invalid instruction order. Dockerfile must begin with &lt;code&gt;FROM&lt;/code&gt;, &lt;code&gt;ARG&lt;/code&gt; or comment.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3062&quot;&gt;DL3062&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Pin versions in go install. Instead of &lt;code&gt;go install &amp;lt;package&amp;gt;&lt;/code&gt; use &lt;code&gt;go install &amp;lt;package&amp;gt;@&amp;lt;version&amp;gt;&lt;/code&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL3063&quot;&gt;DL3063&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Stage name should not be a reserved word&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL4000&quot;&gt;DL4000&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Error&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;MAINTAINER&lt;/code&gt; is deprecated.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL4001&quot;&gt;DL4001&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Either use Wget or Curl but not both.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL4003&quot;&gt;DL4003&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Multiple &lt;code&gt;CMD&lt;/code&gt; instructions found.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL4004&quot;&gt;DL4004&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Error&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Multiple &lt;code&gt;ENTRYPOINT&lt;/code&gt; instructions found.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL4005&quot;&gt;DL4005&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Use &lt;code&gt;SHELL&lt;/code&gt; to change the default shell.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/hadolint/hadolint/wiki/DL4006&quot;&gt;DL4006&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Warning&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Set the &lt;code&gt;SHELL&lt;/code&gt; option -o pipefail before &lt;code&gt;RUN&lt;/code&gt; with a pipe in it&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/SC1000&quot;&gt;SC1000&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;$&lt;/code&gt; is not used specially and should therefore be escaped.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/SC1001&quot;&gt;SC1001&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;This &lt;code&gt;\c&lt;/code&gt; will be a regular &lt;code&gt;&#39;c&#39;&lt;/code&gt; in this context.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/SC1007&quot;&gt;SC1007&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Remove space after &lt;code&gt;=&lt;/code&gt; if trying to assign a value (or for empty string, use &lt;code&gt;var=&#39;&#39; ...&lt;/code&gt;).&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/SC1010&quot;&gt;SC1010&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Use semicolon or linefeed before &lt;code&gt;done&lt;/code&gt; (or quote to make it literal).&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/SC1018&quot;&gt;SC1018&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;This is a unicode non-breaking space. Delete it and retype as space.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/SC1035&quot;&gt;SC1035&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;You need a space here&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/SC1045&quot;&gt;SC1045&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;It&#39;s not &lt;code&gt;foo &amp;amp;; bar&lt;/code&gt;, just &lt;code&gt;foo &amp;amp; bar&lt;/code&gt;.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/SC1065&quot;&gt;SC1065&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Trying to declare parameters? Don&#39;t. Use &lt;code&gt;()&lt;/code&gt; and refer to params as &lt;code&gt;$1&lt;/code&gt;, &lt;code&gt;$2&lt;/code&gt; etc.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/SC1066&quot;&gt;SC1066&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Don&#39;t use $ on the left side of assignments.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/SC1068&quot;&gt;SC1068&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Don&#39;t put spaces around the &lt;code&gt;=&lt;/code&gt; in assignments.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/SC1077&quot;&gt;SC1077&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;For command expansion, the tick should slant left (` vs ´).&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/SC1078&quot;&gt;SC1078&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Did you forget to close this double-quoted string?&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/SC1079&quot;&gt;SC1079&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;This is actually an end quote, but due to next char, it looks suspect.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/SC1081&quot;&gt;SC1081&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Scripts are case sensitive. Use &lt;code&gt;if&lt;/code&gt;, not &lt;code&gt;If&lt;/code&gt;.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/SC1083&quot;&gt;SC1083&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;This &lt;code&gt;{/}&lt;/code&gt; is literal. Check expression (missing &lt;code&gt;;/\n&lt;/code&gt;?) or quote it.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/SC1086&quot;&gt;SC1086&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Don&#39;t use &lt;code&gt;$&lt;/code&gt; on the iterator name in for loops.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/SC1087&quot;&gt;SC1087&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Braces are required when expanding arrays, as in &lt;code&gt;${array[idx]}&lt;/code&gt;.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/SC1091&quot;&gt;SC1091&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Not following: Reasons include: file not found, no permissions, not included on the command line, not allowing shellcheck to follow files with -x, etc.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/SC1095&quot;&gt;SC1095&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;You need a space or linefeed between the function name and body.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/SC1097&quot;&gt;SC1097&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Unexpected &lt;code&gt;==&lt;/code&gt;. For assignment, use &lt;code&gt;=&lt;/code&gt;. For comparison, use &lt;code&gt;[ .. ]&lt;/code&gt; or &lt;code&gt;[[ .. ]]&lt;/code&gt;.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/SC1098&quot;&gt;SC1098&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Quote/escape special characters when using &lt;code&gt;eval&lt;/code&gt;, e.g. &lt;code&gt;eval &quot;a=(b)&quot;&lt;/code&gt;.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/SC1099&quot;&gt;SC1099&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;You need a space before the &lt;code&gt;#&lt;/code&gt;.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/SC2002&quot;&gt;SC2002&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Useless cat. Consider &lt;code&gt;cmd &amp;lt; file | ..&lt;/code&gt; or &lt;code&gt;cmd file | ..&lt;/code&gt; instead.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/SC2015&quot;&gt;SC2015&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Note that &lt;code&gt;A &amp;amp;&amp;amp; B || C&lt;/code&gt; is not if-then-else. C may run when A is true.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/SC2026&quot;&gt;SC2026&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;This word is outside of quotes. Did you intend to &#39;nest &#39;&quot;&#39;single quotes&#39;&quot;&#39; instead&#39;?&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/SC2028&quot;&gt;SC2028&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;echo&lt;/code&gt; won&#39;t expand escape sequences. Consider &lt;code&gt;printf&lt;/code&gt;.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/SC2035&quot;&gt;SC2035&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Use &lt;code&gt;./*glob*&lt;/code&gt; or &lt;code&gt;-- *glob*&lt;/code&gt; so names with dashes won&#39;t become options.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/SC2039&quot;&gt;SC2039&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;In POSIX sh, something is undefined.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/SC2046&quot;&gt;SC2046&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Quote this to prevent word splitting&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/SC2086&quot;&gt;SC2086&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Double quote to prevent globbing and word splitting.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/SC2140&quot;&gt;SC2140&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Word is in the form &lt;code&gt;&quot;A&quot;B&quot;C&quot;&lt;/code&gt; (B indicated). Did you mean &lt;code&gt;&quot;ABC&quot;&lt;/code&gt; or &lt;code&gt;&quot;A\&quot;B\&quot;C&quot;&lt;/code&gt;?&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/SC2154&quot;&gt;SC2154&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;var is referenced but not assigned.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/SC2155&quot;&gt;SC2155&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Declare and assign separately to avoid masking return values.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/SC2164&quot;&gt;SC2164&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:left&quot;&gt;Use &lt;code&gt;cd ... || exit&lt;/code&gt; in case &lt;code&gt;cd&lt;/code&gt; fails.&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;!--lint enable maximum-line-length--&gt; 
&lt;h2&gt;Develop&lt;/h2&gt; 
&lt;p&gt;If you are an experienced Haskeller, we would be very grateful if you would tear our code apart in a review.&lt;/p&gt; 
&lt;p&gt;To compile, you will need a recent Haskell environment and &lt;code&gt;cabal-install&lt;/code&gt;.&lt;/p&gt; 
&lt;h3&gt;Setup&lt;/h3&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;Clone repository&lt;/p&gt; &lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git clone --recursive git@github.com:hadolint/hadolint.git
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Install dependencies and compile source&lt;/p&gt; &lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;cabal configure
cabal update
cabal build
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;(Optional) Install Hadolint on your system&lt;/p&gt; &lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;cabal install
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;h3&gt;REPL&lt;/h3&gt; 
&lt;p&gt;The easiest way to try out the parser is using the REPL.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# start the repl
cabal repl
# overload strings to be able to use Text
:set -XOverloadedStrings
# import parser library
import Language.Docker
# parse instruction and look at AST representation
parseText &quot;FROM debian:jessie&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Tests&lt;/h3&gt; 
&lt;p&gt;Compile with unit tests and run them:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;cabal configure --enable-tests
cabal build --enable-tests
cabal test
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Run integration tests:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;./integration_test.sh
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;AST&lt;/h3&gt; 
&lt;p&gt;Dockerfile syntax is fully described in the &lt;a href=&quot;http://docs.docker.com/engine/reference/builder/&quot;&gt;Dockerfile reference&lt;/a&gt;. Just take a look at &lt;a href=&quot;https://www.stackage.org/haddock/nightly-2022-11-15/language-docker-12.0.0/Language-Docker-Syntax.html&quot;&gt;Syntax.hs&lt;/a&gt; in the &lt;code&gt;language-docker&lt;/code&gt; project to see the AST definition.&lt;/p&gt; 
&lt;h3&gt;Building against custom libraries&lt;/h3&gt; 
&lt;p&gt;Hadolint uses many libraries to do the dirty work. In particular, language-docker is used to parse Dockerfiles and produce an AST which then can be analyzed. To build Hadolint against a custom version of such libraries, do the following. This example uses language-docker, but it would work with any other library as well.&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;In the same directory (e.g. &lt;code&gt;/home/user/repos&lt;/code&gt;) clone Hadolint and language-docker git repositories&lt;/li&gt; 
&lt;/ol&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;cd /home/user/repos
git clone https://github.com/hadolint/hadolint.git
git clone https://github.com/hadolint/language-docker.git
&lt;/code&gt;&lt;/pre&gt; 
&lt;ol start=&quot;2&quot;&gt; 
 &lt;li&gt; &lt;p&gt;Make your modifications to language-docker&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;In the Hadolint repo, edit the &lt;code&gt;cabal.project&lt;/code&gt; file, such that the &lt;code&gt;packages&lt;/code&gt; property points to the other repo too&lt;/p&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;[...]
packages:
  .
  ../language-docker
[...]
&lt;/code&gt;&lt;/pre&gt; 
&lt;ol start=&quot;4&quot;&gt; 
 &lt;li&gt;Recompile Hadolint and run the tests&lt;/li&gt; 
&lt;/ol&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;cd /home/user/repos/hadolint
cabal configure --enable-tests
cabal build --enable-tests
cabal test
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Alternatives&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;replicatedhq/&lt;a href=&quot;https://github.com/replicatedhq/dockerfilelint&quot;&gt;dockerfilelint&lt;/a&gt;, the other linter used by the &lt;a href=&quot;https://github.com/github/super-linter/raw/main/README.md#supported-linters&quot;&gt;super-linter&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;RedCoolBeans/&lt;a href=&quot;https://github.com/RedCoolBeans/dockerlint/&quot;&gt;dockerlint&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;projectatomic/&lt;a href=&quot;https://github.com/projectatomic/dockerfile_lint/&quot;&gt;dockerfile_lint&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;!-- References --&gt;</description>
      
      <media:content url="https://opengraph.githubassets.com/1e90575ff47f84e5f88f6cfa1b56b99ed7d886314c11b9327829c58f554fad65/hadolint/hadolint" medium="image" />
      
    </item>
    
    <item>
      <title>simplex-chat/simplex-chat</title>
      <link>https://github.com/simplex-chat/simplex-chat</link>
      <description>&lt;p&gt;SimpleX - the first messaging network operating without user identifiers of any kind - 100% private by design! iOS, Android and desktop apps 📱!&lt;/p&gt;&lt;hr&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/simplex-chat/simplex-chat/actions/workflows/build.yml&quot;&gt;&lt;img src=&quot;https://github.com/simplex-chat/simplex-chat/actions/workflows/build.yml/badge.svg?branch=stable&quot; alt=&quot;build&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://github.com/simplex-chat/simplex-chat/releases&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/downloads/simplex-chat/simplex-chat/total&quot; alt=&quot;GitHub downloads&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://github.com/simplex-chat/simplex-chat/releases&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/v/release/simplex-chat/simplex-chat&quot; alt=&quot;GitHub release&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://www.reddit.com/r/SimpleXChat&quot;&gt;&lt;img src=&quot;https://img.shields.io/reddit/subreddit-subscribers/SimpleXChat?style=social&quot; alt=&quot;Join on Reddit&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;me&quot; href=&quot;https://mastodon.social/@simplex&quot;&gt;&lt;img src=&quot;https://img.shields.io/mastodon/follow/108619463746856738?domain=https%3A%2F%2Fmastodon.social&amp;amp;style=social&quot; alt=&quot;Follow on Mastodon&quot; /&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;| 30/03/2023 | EN, &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/docs/lang/fr/README.md&quot;&gt;FR&lt;/a&gt;, &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/docs/lang/cs/README.md&quot;&gt;CZ&lt;/a&gt;, &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/docs/lang/pl/README.md&quot;&gt;PL&lt;/a&gt; |&lt;/p&gt; 
&lt;img src=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/images/simplex-chat-logo.svg?sanitize=true&quot; alt=&quot;SimpleX logo&quot; width=&quot;100%&quot; /&gt; 
&lt;h1&gt;SimpleX - the first messaging platform that has no user identifiers of any kind - 100% private by design!&lt;/h1&gt; 
&lt;p&gt;&lt;a href=&quot;http://simplex.chat/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html&quot;&gt;&lt;img src=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/images/trail-of-bits.jpg&quot; height=&quot;80&quot; /&gt;&lt;/a&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;a href=&quot;https://www.privacyguides.org/en/real-time-communication/#simplex-chat&quot;&gt;&lt;img src=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/images/privacy-guides.jpg&quot; height=&quot;64&quot; /&gt;&lt;/a&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;a href=&quot;https://www.whonix.org/wiki/Chat#Recommendation&quot;&gt;&lt;img src=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/images/whonix-logo.jpg&quot; height=&quot;64&quot; /&gt;&lt;/a&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;a href=&quot;https://www.kuketz-blog.de/simplex-eindruecke-vom-messenger-ohne-identifier/&quot;&gt;&lt;img src=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/images/kuketz-blog.jpg&quot; height=&quot;64&quot; /&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/docs/WHY.md&quot;&gt;Why we are building SimpleX Network&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;h2&gt;Welcome to SimpleX Chat!&lt;/h2&gt; 
&lt;ol&gt; 
 &lt;li&gt;📲 &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/#install-the-app&quot;&gt;Install the app&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;↔️ &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/#connect-to-the-team&quot;&gt;Connect to the team&lt;/a&gt;, &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/#join-user-groups&quot;&gt;join user groups&lt;/a&gt; and &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/#follow-our-updates&quot;&gt;follow our updates&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;🤝 &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/#make-a-private-connection&quot;&gt;Make a private connection&lt;/a&gt; with a friend.&lt;/li&gt; 
 &lt;li&gt;🔤 &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/#help-translating-simplex-chat&quot;&gt;Help translating SimpleX Chat&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;⚡️ &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/#contribute&quot;&gt;Contribute&lt;/a&gt; and &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/#please-support-us-with-your-donations&quot;&gt;support us with donations&lt;/a&gt;.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/#contents&quot;&gt;Learn more about SimpleX Chat&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;Install the app&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://apps.apple.com/us/app/simplex-chat/id1605771084&quot;&gt;&lt;img src=&quot;https://raw.githubusercontent.com/simplex-chat/.github/refs/heads/master/profile/images/apple_store.svg?sanitize=true&quot; alt=&quot;iOS app&quot; height=&quot;42&quot; /&gt;&lt;/a&gt; &amp;nbsp; &lt;a href=&quot;https://play.google.com/store/apps/details?id=chat.simplex.app&quot;&gt;&lt;img src=&quot;https://raw.githubusercontent.com/simplex-chat/.github/refs/heads/master/profile/images/google_play.svg?sanitize=true&quot; alt=&quot;Android app&quot; /&gt;&lt;/a&gt; &amp;nbsp; &lt;a href=&quot;https://app.simplex.chat&quot;&gt;&lt;img src=&quot;https://raw.githubusercontent.com/simplex-chat/.github/refs/heads/master/profile/images/f_droid.svg?sanitize=true&quot; alt=&quot;F-Droid&quot; height=&quot;41&quot; /&gt;&lt;/a&gt; &amp;nbsp; &lt;a href=&quot;https://testflight.apple.com/join/DWuT2LQu&quot;&gt;&lt;img src=&quot;https://raw.githubusercontent.com/simplex-chat/.github/refs/heads/master/profile/images/testflight.png&quot; alt=&quot;iOS TestFlight&quot; height=&quot;41&quot; /&gt;&lt;/a&gt; &amp;nbsp; &lt;a href=&quot;https://github.com/simplex-chat/simplex-chat/releases/latest/download/simplex-aarch64.apk&quot;&gt;&lt;img src=&quot;https://raw.githubusercontent.com/simplex-chat/.github/refs/heads/master/profile/images/apk_icon.png&quot; alt=&quot;APK&quot; height=&quot;41&quot; /&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;🖲 Protects your messages and metadata - who you talk to and when.&lt;/li&gt; 
 &lt;li&gt;🔐 Double ratchet end-to-end encryption, with additional encryption layer.&lt;/li&gt; 
 &lt;li&gt;📱 Mobile apps for Android (&lt;a href=&quot;https://play.google.com/store/apps/details?id=chat.simplex.app&quot;&gt;Google Play&lt;/a&gt;, &lt;a href=&quot;https://github.com/simplex-chat/simplex-chat/releases/latest/download/simplex-aarch64.apk&quot;&gt;APK&lt;/a&gt;) and &lt;a href=&quot;https://apps.apple.com/us/app/simplex-chat/id1605771084&quot;&gt;iOS&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;🚀 &lt;a href=&quot;https://testflight.apple.com/join/DWuT2LQu&quot;&gt;TestFlight preview for iOS&lt;/a&gt; with the new features 1-2 weeks earlier - &lt;strong&gt;limited to 10,000 users&lt;/strong&gt;!&lt;/li&gt; 
 &lt;li&gt;🖥 Available as a terminal (console) &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/#zap-quick-installation-of-a-terminal-app&quot;&gt;app / CLI&lt;/a&gt; on Linux, MacOS, Windows.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Connect to the team&lt;/h2&gt; 
&lt;p&gt;You can connect to the team via the app using &quot;chat with the developers button&quot; available when you have no conversations in the profile, &quot;Send questions and ideas&quot; in the app settings or via our &lt;a href=&quot;https://smp6.simplex.im/a#lrdvu2d8A1GumSmoKb2krQmtKhWXq-tyGpHuM7aMwsw&quot;&gt;SimpleX address&lt;/a&gt;. Please connect to:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;to ask any questions&lt;/li&gt; 
 &lt;li&gt;to suggest any improvements&lt;/li&gt; 
 &lt;li&gt;to share anything relevant&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;We are replying the questions manually, so it is not instant – it can take up to 24 hours.&lt;/p&gt; 
&lt;p&gt;If you are interested in helping us to integrate open-source language models, and in &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/docs/JOIN_TEAM.md&quot;&gt;joining our team&lt;/a&gt;, please get in touch.&lt;/p&gt; 
&lt;h2&gt;Join user groups&lt;/h2&gt; 
&lt;p&gt;You can find the groups created by users in &lt;a href=&quot;https://simplex.chat/directory/&quot;&gt;SimpleX Directory&lt;/a&gt;. It is also available as &lt;a href=&quot;https://smp4.simplex.im/a#lXUjJW5vHYQzoLYgmi8GbxkGP41_kjefFvBrdwg-0Ok&quot;&gt;SimpleX bot&lt;/a&gt; that allows to add your own groups and communities to the directory. We are not responsible for the content shared in these groups.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Please note&lt;/strong&gt;: The groups below are created for the users to be able to ask questions, make suggestions and ask questions about SimpleX Chat only.&lt;/p&gt; 
&lt;p&gt;You can join an English-speaking users group if you want to ask any questions: &lt;a href=&quot;https://smp4.simplex.im/g#hr4lvFeBmndWMKTwqiodPz3VBo_6UmdGWocXd1SupsM&quot;&gt;#SimpleX users group&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;There is also a group &lt;a href=&quot;https://smp6.simplex.im/g#Drx3efC-n418AuSpzTspw9SER0iJwrQTmKBafQHwkKM&quot;&gt;#simplex-devs&lt;/a&gt; for developers who build on SimpleX platform:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;chat bots and automations&lt;/li&gt; 
 &lt;li&gt;integrations with other apps&lt;/li&gt; 
 &lt;li&gt;social apps and services&lt;/li&gt; 
 &lt;li&gt;etc.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;You can join these and other groups by opening these links in the app or by opening them in a desktop browser and scanning the QR code.&lt;/p&gt; 
&lt;h2&gt;Follow our updates&lt;/h2&gt; 
&lt;p&gt;We publish our updates and releases via:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.reddit.com/r/SimpleXChat/&quot;&gt;Reddit&lt;/a&gt;, &lt;a href=&quot;https://twitter.com/SimpleXChat&quot;&gt;Twitter&lt;/a&gt;, &lt;a href=&quot;https://lemmy.ml/c/simplex&quot;&gt;Lemmy&lt;/a&gt;, &lt;a href=&quot;https://mastodon.social/@simplex&quot;&gt;Mastodon&lt;/a&gt; and &lt;a href=&quot;https://snort.social/p/npub1exv22uulqnmlluszc4yk92jhs2e5ajcs6mu3t00a6avzjcalj9csm7d828&quot;&gt;Nostr&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;SimpleX Chat &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/#connect-to-the-team&quot;&gt;team profile&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://simplex.chat/blog/&quot;&gt;blog&lt;/a&gt; and &lt;a href=&quot;https://simplex.chat/feed.rss&quot;&gt;RSS feed&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://simplex.chat/#join-simplex&quot;&gt;mailing list&lt;/a&gt;, very rarely.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Make a private connection&lt;/h2&gt; 
&lt;p&gt;You need to share a link with your friend or scan a QR code from their phone, in person or during a video call, to make a connection and start messaging.&lt;/p&gt; 
&lt;p&gt;The channel through which you share the link does not have to be secure - it is enough that you can confirm who sent you the message and that your SimpleX connection is established.&lt;/p&gt; 
&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/simplex-chat/.github/refs/heads/master/profile/images/app1.png&quot; alt=&quot;Make a private connection&quot; height=&quot;360&quot; /&gt; &lt;img src=&quot;https://raw.githubusercontent.com/simplex-chat/.github/refs/heads/master/profile/images/arrow.png&quot; height=&quot;360&quot; /&gt; &lt;img src=&quot;https://raw.githubusercontent.com/simplex-chat/.github/refs/heads/master/profile/images/app2.png&quot; alt=&quot;Conversation&quot; height=&quot;360&quot; /&gt; &lt;img src=&quot;https://raw.githubusercontent.com/simplex-chat/.github/refs/heads/master/profile/images/arrow.png&quot; height=&quot;360&quot; /&gt; &lt;img src=&quot;https://raw.githubusercontent.com/simplex-chat/.github/refs/heads/master/profile/images/app3.png&quot; alt=&quot;Video call&quot; height=&quot;360&quot; /&gt;&lt;/p&gt; 
&lt;p&gt;After you connect, you can &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/blog/20230103-simplex-chat-v4.4-disappearing-messages.md#connection-security-verification&quot;&gt;verify connection security code&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;User guide (NEW)&lt;/h2&gt; 
&lt;p&gt;Read about the app features and settings in the new &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/docs/guide/README.md&quot;&gt;User guide&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;Contribute&lt;/h2&gt; 
&lt;p&gt;We would love to have you join the development! You can help us with:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/#develop-a-chat-bot&quot;&gt;develop a chat bot&lt;/a&gt; for SimpleX Chat!&lt;/li&gt; 
 &lt;li&gt;writing a tutorial or recipes about hosting servers, chat bots, etc.&lt;/li&gt; 
 &lt;li&gt;developing features - please connect to us via chat so we can help you get started.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Help translating SimpleX Chat&lt;/h2&gt; 
&lt;p&gt;Thanks to our users and &lt;a href=&quot;https://hosted.weblate.org/engage/simplex-chat/&quot;&gt;Weblate&lt;/a&gt;, SimpleX Chat apps, website and documents are translated to many other languages.&lt;/p&gt; 
&lt;p&gt;Join our translators to help SimpleX grow!&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt; 
   &lt;th style=&quot;text-align:center&quot;&gt;locale&lt;/th&gt; 
   &lt;th style=&quot;text-align:center&quot;&gt;language&lt;/th&gt; 
   &lt;th style=&quot;text-align:center&quot;&gt;contributor&lt;/th&gt; 
   &lt;th style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://play.google.com/store/apps/details?id=chat.simplex.app&quot;&gt;Android&lt;/a&gt; and &lt;a href=&quot;https://apps.apple.com/us/app/simplex-chat/id1605771084&quot;&gt;iOS&lt;/a&gt;&lt;/th&gt; 
   &lt;th style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://simplex.chat&quot;&gt;website&lt;/a&gt;&lt;/th&gt; 
   &lt;th style=&quot;text-align:center&quot;&gt;Github docs&lt;/th&gt; 
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;🇬🇧 en&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;English&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;✓&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;✓&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;✓&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;ar&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;العربية&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://github.com/jermanuts&quot;&gt;jermanuts&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/android/ar/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/ar/android/svg-badge.svg?sanitize=true&quot; alt=&quot;android app&quot; /&gt;&lt;/a&gt;&lt;br /&gt;-&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/website/ar/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/ar/website/svg-badge.svg?sanitize=true&quot; alt=&quot;website&quot; /&gt;&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;🇧🇬 bg&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;Български&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/android/bg/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/bg/android/svg-badge.svg?sanitize=true&quot; alt=&quot;android app&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/ios/bg/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widget/simplex-chat/ios/bg/svg-badge.svg?sanitize=true&quot; alt=&quot;ios app&quot; /&gt;&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;🇨🇿 cs&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;Čeština&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://github.com/zen0bit&quot;&gt;zen0bit&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/android/cs/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/cs/android/svg-badge.svg?sanitize=true&quot; alt=&quot;android app&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/ios/cs/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/cs/ios/svg-badge.svg?sanitize=true&quot; alt=&quot;ios app&quot; /&gt;&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/website/cs/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/cs/website/svg-badge.svg?sanitize=true&quot; alt=&quot;website&quot; /&gt;&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://github.com/simplex-chat/simplex-chat/tree/master/docs/lang/cs&quot;&gt;✓&lt;/a&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;🇩🇪 de&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;Deutsch&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://github.com/mlanp&quot;&gt;mlanp&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/android/de/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/de/android/svg-badge.svg?sanitize=true&quot; alt=&quot;android app&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/ios/de/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/de/ios/svg-badge.svg?sanitize=true&quot; alt=&quot;ios app&quot; /&gt;&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/website/de/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/de/website/svg-badge.svg?sanitize=true&quot; alt=&quot;website&quot; /&gt;&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;🇪🇸 es&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;Español&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://github.com/Mateyhv&quot;&gt;Mateyhv&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/android/es/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/es/android/svg-badge.svg?sanitize=true&quot; alt=&quot;android app&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/ios/es/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/es/ios/svg-badge.svg?sanitize=true&quot; alt=&quot;ios app&quot; /&gt;&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/website/es/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/es/website/svg-badge.svg?sanitize=true&quot; alt=&quot;website&quot; /&gt;&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;🇫🇮 fi&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;Suomi&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/android/fi/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/fi/android/svg-badge.svg?sanitize=true&quot; alt=&quot;android app&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/ios/fi/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/fi/ios/svg-badge.svg?sanitize=true&quot; alt=&quot;ios app&quot; /&gt;&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/website/fi/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/fi/website/svg-badge.svg?sanitize=true&quot; alt=&quot;website&quot; /&gt;&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;🇫🇷 fr&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;Français&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://github.com/ishi-sama&quot;&gt;ishi_sama&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/android/fr/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/fr/android/svg-badge.svg?sanitize=true&quot; alt=&quot;android app&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/ios/fr/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/fr/ios/svg-badge.svg?sanitize=true&quot; alt=&quot;ios app&quot; /&gt;&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/website/fr/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/fr/website/svg-badge.svg?sanitize=true&quot; alt=&quot;website&quot; /&gt;&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://github.com/simplex-chat/simplex-chat/tree/master/docs/lang/fr&quot;&gt;✓&lt;/a&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;🇮🇱 he&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;עִברִית&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/android/he/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/he/android/svg-badge.svg?sanitize=true&quot; alt=&quot;android app&quot; /&gt;&lt;/a&gt;&lt;br /&gt;-&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;🇭🇺 hu&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;Magyar&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/android/hu/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/hu/android/svg-badge.svg?sanitize=true&quot; alt=&quot;android app&quot; /&gt;&lt;/a&gt;&lt;br /&gt;-&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;🇮🇹 it&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;Italiano&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://github.com/unbranched&quot;&gt;unbranched&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/android/it/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/it/android/svg-badge.svg?sanitize=true&quot; alt=&quot;android app&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/ios/it/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/it/ios/svg-badge.svg?sanitize=true&quot; alt=&quot;ios app&quot; /&gt;&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/website/it/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/it/website/svg-badge.svg?sanitize=true&quot; alt=&quot;website&quot; /&gt;&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;🇯🇵 ja&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;日本語&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/android/ja/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/ja/android/svg-badge.svg?sanitize=true&quot; alt=&quot;android app&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/ios/ja/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/ja/ios/svg-badge.svg?sanitize=true&quot; alt=&quot;ios app&quot; /&gt;&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/website/ja/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/ja/website/svg-badge.svg?sanitize=true&quot; alt=&quot;website&quot; /&gt;&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;🇳🇱 nl&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;Nederlands&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://github.com/mika-nl&quot;&gt;mika-nl&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/android/nl/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/nl/android/svg-badge.svg?sanitize=true&quot; alt=&quot;android app&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/ios/nl/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/nl/ios/svg-badge.svg?sanitize=true&quot; alt=&quot;ios app&quot; /&gt;&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/website/nl/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/nl/website/svg-badge.svg?sanitize=true&quot; alt=&quot;website&quot; /&gt;&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;🇵🇱 pl&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;Polski&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://github.com/BxOxSxS&quot;&gt;BxOxSxS&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/android/pl/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/pl/android/svg-badge.svg?sanitize=true&quot; alt=&quot;android app&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/ios/pl/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/pl/ios/svg-badge.svg?sanitize=true&quot; alt=&quot;ios app&quot; /&gt;&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;🇧🇷 pt-BR&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;Português&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/android/pt_BR/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/pt_BR/android/svg-badge.svg?sanitize=true&quot; alt=&quot;android app&quot; /&gt;&lt;/a&gt;&lt;br /&gt;-&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/website/pt_BR/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/pt_BR/website/svg-badge.svg?sanitize=true&quot; alt=&quot;website&quot; /&gt;&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;🇷🇺 ru&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;Русский&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/android/ru/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/ru/android/svg-badge.svg?sanitize=true&quot; alt=&quot;android app&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/ios/ru/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/ru/ios/svg-badge.svg?sanitize=true&quot; alt=&quot;ios app&quot; /&gt;&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;🇹🇭 th&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;ภาษาไทย&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://github.com/titapa-punpun&quot;&gt;titapa-punpun&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/android/th/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/th/android/svg-badge.svg?sanitize=true&quot; alt=&quot;android app&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/ios/th/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/th/ios/svg-badge.svg?sanitize=true&quot; alt=&quot;ios app&quot; /&gt;&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;🇹🇷 tr&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;Türkçe&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/android/tr/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/tr/android/svg-badge.svg?sanitize=true&quot; alt=&quot;android app&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/ios/tr/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/tr/ios/svg-badge.svg?sanitize=true&quot; alt=&quot;ios app&quot; /&gt;&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;🇺🇦 uk&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;Українська&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/android/uk/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/uk/android/svg-badge.svg?sanitize=true&quot; alt=&quot;android app&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/ios/uk/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/uk/ios/svg-badge.svg?sanitize=true&quot; alt=&quot;ios app&quot; /&gt;&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/website/uk/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/uk/website/svg-badge.svg?sanitize=true&quot; alt=&quot;website&quot; /&gt;&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;🇨🇳 zh-CHS&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;简体中文&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://github.com/sith-on-mars&quot;&gt;sith-on-mars&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;https://github.com/Float-hu&quot;&gt;Float-hu&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/android/zh_Hans/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/zh_Hans/android/svg-badge.svg?sanitize=true&quot; alt=&quot;android app&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/ios/zh_Hans/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/zh_Hans/ios/svg-badge.svg?sanitize=true&quot; alt=&quot;ios app&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&amp;nbsp;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/website/zh_Hans/&quot;&gt;&lt;img src=&quot;https://hosted.weblate.org/widgets/simplex-chat/zh_Hans/website/svg-badge.svg?sanitize=true&quot; alt=&quot;website&quot; /&gt;&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;Languages in progress: Arabic, Japanese, Korean, Portuguese and &lt;a href=&quot;https://hosted.weblate.org/projects/simplex-chat/#languages&quot;&gt;others&lt;/a&gt;. We will be adding more languages as some of the already added are completed – please suggest new languages, review the &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/docs/TRANSLATIONS.md&quot;&gt;translation guide&lt;/a&gt; and get in touch with us!&lt;/p&gt; 
&lt;h2&gt;Please support us with your donations&lt;/h2&gt; 
&lt;p&gt;Huge thank you to everybody who donated to SimpleX Chat!&lt;/p&gt; 
&lt;p&gt;We are prioritizing users privacy and security - it would be impossible without your support.&lt;/p&gt; 
&lt;p&gt;Our pledge to our users is that SimpleX protocols are and will remain open, and in public domain, - so anybody can build the future implementations of the clients and the servers. We are building SimpleX platform based on the same principles as email and web, but much more private and secure.&lt;/p&gt; 
&lt;p&gt;Your donations help us raise more funds - any amount, even the price of the cup of coffee, would make a big difference for us.&lt;/p&gt; 
&lt;p&gt;It is possible to donate via:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/sponsors/simplex-chat&quot;&gt;GitHub&lt;/a&gt; (commission-free) or &lt;a href=&quot;https://opencollective.com/simplex-chat&quot;&gt;OpenCollective&lt;/a&gt; (~10% commission).&lt;/li&gt; 
 &lt;li&gt;BTC: bc1q2gy6f02nn6vvcxs0pnu29tpnpyz0qf66505d4u&lt;/li&gt; 
 &lt;li&gt;XMR: 8A3ZWAXrrQddvnT1fPrtbK86ZAoM4nai3Gjg1LEow3JWcryJtovMnHYZnxTJpCLmAbfWbnPMeTzPmMBjAhyd4xoM89hYq1c&lt;/li&gt; 
 &lt;li&gt;BCH: bitcoincash:qq6c8vfvxqrk6rhdysgvkhqc24sggkfsx5nqvdlqcg&lt;/li&gt; 
 &lt;li&gt;ETH/USDT (Ethereum, Arbitrum One): 0xD7047Fe3Eecb2f2FF78d839dD927Be27Bc12c86a (donate.simplexchat.eth)&lt;/li&gt; 
 &lt;li&gt;ZEC: t1fwjQW5gpFhDqXNhxqDWyF9j9WeKvVS5Jg&lt;/li&gt; 
 &lt;li&gt;ZEC shielded: u16rnvkflumf5uw9frngc2lymvmzgdr2mmc9unyu0l44unwfmdcpfm0axujd2w34ct3ye709azxsqge45705lpvvqu264ltzvfay55ygyq&lt;/li&gt; 
 &lt;li&gt;DOGE: D99pV4n9TrPxBPCkQGx4w4SMSa6QjRBxPf&lt;/li&gt; 
 &lt;li&gt;SOL: 7JCf5m3TiHmYKZVr6jCu1KeZVtb9Y1jRMQDU69p5ARnu&lt;/li&gt; 
 &lt;li&gt;please ask if you want to donate any other coins.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Thank you,&lt;/p&gt; 
&lt;p&gt;Evgeny&lt;/p&gt; 
&lt;p&gt;SimpleX Chat founder&lt;/p&gt; 
&lt;h2&gt;Contents&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/#why-privacy-matters&quot;&gt;Why privacy matters&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/#simplex-approach-to-privacy-and-security&quot;&gt;SimpleX approach to privacy and security&lt;/a&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/#complete-privacy-of-your-identity-profile-contacts-and-metadata&quot;&gt;Complete privacy&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/#the-best-protection-against-spam-and-abuse&quot;&gt;Protection against spam and abuse&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/#complete-ownership-control-and-security-of-your-data&quot;&gt;Ownership and security of your data&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/#users-own-simplex-network&quot;&gt;Users own SimpleX network&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/#frequently-asked-questions&quot;&gt;Frequently asked questions&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/#news-and-updates&quot;&gt;News and updates&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/#zap-quick-installation-of-a-terminal-app&quot;&gt;Quick installation of a terminal app&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/#simplex-platform-design&quot;&gt;SimpleX Platform design&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/#privacy-and-security-technical-details-and-limitations&quot;&gt;Privacy and security: technical details and limitations&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/#for-developers&quot;&gt;For developers&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/#develop-a-chat-bot&quot;&gt;Develop a chat bot&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/#roadmap&quot;&gt;Roadmap&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/#disclaimers&quot;&gt;Disclaimers, Security contact, License&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Why privacy matters&lt;/h2&gt; 
&lt;p&gt;Everyone should care about privacy and security of their communications - innocuous conversations can put you in danger even if there is nothing to hide.&lt;/p&gt; 
&lt;p&gt;One of the most shocking stories is the experience of &lt;a href=&quot;https://en.wikipedia.org/wiki/Mohamedou_Ould_Slahi&quot;&gt;Mohamedou Ould Salahi&lt;/a&gt; that he wrote about in his memoir and that is shown in The Mauritanian movie. He was put into Guantanamo camp, without trial, and was tortured there for 15 years after a phone call to his relative in Afghanistan, under suspicion of being involved in 9/11 attacks, even though he lived in Germany for the 10 years prior to the attacks.&lt;/p&gt; 
&lt;p&gt;It is not enough to use an end-to-end encrypted messenger, we all should use the messengers that protect the privacy of our personal networks - who we are connected with.&lt;/p&gt; 
&lt;h2&gt;SimpleX approach to privacy and security&lt;/h2&gt; 
&lt;h3&gt;Complete privacy of your identity, profile, contacts and metadata&lt;/h3&gt; 
&lt;p&gt;&lt;strong&gt;Unlike any other existing messaging platform, SimpleX has no identifiers assigned to the users&lt;/strong&gt; - not even random numbers. This protects the privacy of who are you communicating with, hiding it from SimpleX platform servers and from any observers. &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/docs/SIMPLEX.md#full-privacy-of-your-identity-profile-contacts-and-metadata&quot;&gt;Read more&lt;/a&gt;.&lt;/p&gt; 
&lt;h3&gt;The best protection against spam and abuse&lt;/h3&gt; 
&lt;p&gt;As you have no identifier on SimpleX platform, you cannot be contacted unless you share a one-time invitation link or an optional temporary user address. &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/docs/SIMPLEX.md#the-best-protection-against-spam-and-abuse&quot;&gt;Read more&lt;/a&gt;.&lt;/p&gt; 
&lt;h3&gt;Complete ownership, control and security of your data&lt;/h3&gt; 
&lt;p&gt;SimpleX stores all user data on client devices, the messages are only held temporarily on SimpleX relay servers until they are received. &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/docs/SIMPLEX.md#complete-ownership-control-and-security-of-your-data&quot;&gt;Read more&lt;/a&gt;.&lt;/p&gt; 
&lt;h3&gt;Users own SimpleX network&lt;/h3&gt; 
&lt;p&gt;You can use SimpleX with your own servers and still communicate with people using the servers that are pre-configured in the apps or any other SimpleX servers. &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/docs/SIMPLEX.md#users-own-simplex-network&quot;&gt;Read more&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;Frequently asked questions&lt;/h2&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;&lt;em&gt;How SimpleX can deliver messages without any user identifiers?&lt;/em&gt; See &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/blog/20220511-simplex-chat-v2-images-files.md#the-first-messaging-platform-without-user-identifiers&quot;&gt;v2 release announcement&lt;/a&gt; explaining how SimpleX works.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;em&gt;Why should I not just use Signal?&lt;/em&gt; Signal is a centralized platform that uses phone numbers to identify its users and their contacts. It means that while the content of your messages on Signal is protected with robust end-to-end encryption, there is a large amount of meta-data visible to Signal - who you talk with and when.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;em&gt;How is it different from Matrix, Session, Ricochet, Cwtch, etc., that also don&#39;t require user identities?&lt;/em&gt; Although these platforms do not require a &lt;em&gt;real identity&lt;/em&gt;, they do rely on anonymous user identities to deliver messages – it can be, for example, an identity key or a random number. Using a persistent user identity, even anonymous, creates a risk that user&#39;s connection graph becomes known to the observers and/or service providers, and it can lead to de-anonymizing some users. If the same user profile is used to connect to two different people via any messenger other than SimpleX, these two people can confirm if they are connected to the same person - they would use the same user identifier in the messages. With SimpleX there is no meta-data in common between your conversations with different contacts - the quality that no other messaging platform has.&lt;/p&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;h2&gt;News and updates&lt;/h2&gt; 
&lt;p&gt;Recent and important updates:&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/blog/20250729-simplex-chat-v6-4-1-welcome-contacts-protect-groups-app-security.md&quot;&gt;Jul 29, 2025 SimpleX Chat v6.4.1: welcome your contacts, review members to protect groups, and more.&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/blog/20250703-simplex-network-protocol-extension-for-securely-connecting-people.md&quot;&gt;Jul 3, 2025 SimpleX network: new experience of connecting with people — available in SimpleX Chat v6.4-beta.4&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/blog/20250308-simplex-chat-v6-3-new-user-experience-safety-in-public-groups.md&quot;&gt;Mar 8, 2025. SimpleX Chat v6.3: new user experience and safety in public groups&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/blog/20250114-simplex-network-large-groups-privacy-preserving-content-moderation.md&quot;&gt;Jan 14, 2025. SimpleX network: large groups and privacy-preserving content moderation&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/20241210-simplex-network-v6-2-servers-by-flux-business-chats.md&quot;&gt;Dec 10, 2024. SimpleX network: preset servers operated by Flux, business chats and more with v6.2 of the apps&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/blog/20241014-simplex-network-v6-1-security-review-better-calls-user-experience.md&quot;&gt;Oct 14, 2024. SimpleX network: security review of protocols design by Trail of Bits, v6.1 released with better calls and user experience.&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/blog/20240814-simplex-chat-vision-funding-v6-private-routing-new-user-experience.md&quot;&gt;Aug 14, 2024. SimpleX network: the investment from Jack Dorsey and Asymmetric, v6.0 released with the new user experience and private message routing&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/blog/20240604-simplex-chat-v5.8-private-message-routing-chat-themes.md&quot;&gt;Jun 4, 2024. SimpleX network: private message routing, v5.8 released with IP address protection and chat themes&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/blog/20240314-simplex-chat-v5-6-quantum-resistance-signal-double-ratchet-algorithm.md&quot;&gt;Mar 14, 2024. SimpleX Chat v5.6 beta: adding quantum resistance to Signal double ratchet algorithm.&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/blog/20231125-simplex-chat-v5-4-link-mobile-desktop-quantum-resistant-better-groups.md&quot;&gt;Nov 25, 2023. SimpleX Chat v5.4 released: link mobile and desktop apps via quantum resistant protocol, and much better groups&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/blog/20230422-simplex-chat-vision-funding-v5-videos-files-passcode.md&quot;&gt;Apr 22, 2023. SimpleX Chat: vision and funding, v5.0 released with videos and files up to 1gb&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/blog/20230301-simplex-file-transfer-protocol.md&quot;&gt;Mar 1, 2023. SimpleX File Transfer Protocol – send large files efficiently, privately and securely, soon to be integrated into SimpleX Chat apps.&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/blog/20221108-simplex-chat-v4.2-security-audit-new-website.md&quot;&gt;Nov 8, 2022. Security audit by Trail of Bits, the new website and v4.2 released&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/blog&quot;&gt;All updates&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;⚡ Quick installation of a terminal app&lt;/h2&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;curl -o- https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/install.sh | bash
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Once the chat client is installed, simply run &lt;code&gt;simplex-chat&lt;/code&gt; from your terminal.&lt;/p&gt; 
&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/images/connection.gif&quot; alt=&quot;simplex-chat&quot; /&gt;&lt;/p&gt; 
&lt;p&gt;Read more about &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/docs/CLI.md&quot;&gt;installing and using the terminal app&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;SimpleX Platform design&lt;/h2&gt; 
&lt;p&gt;SimpleX is a client-server network with a unique network topology that uses redundant, disposable message relay nodes to asynchronously pass messages via unidirectional (simplex) message queues, providing recipient and sender anonymity.&lt;/p&gt; 
&lt;p&gt;Unlike P2P networks, all messages are passed through one or several server nodes, that do not even need to have persistence. In fact, the current &lt;a href=&quot;https://github.com/simplex-chat/simplexmq#smp-server&quot;&gt;SMP server implementation&lt;/a&gt; uses in-memory message storage, persisting only the queue records. SimpleX provides better metadata protection than P2P designs, as no global participant identifiers are used to deliver messages, and avoids &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/docs/SIMPLEX.md#comparison-with-p2p-messaging-protocols&quot;&gt;the problems of P2P networks&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;Unlike federated networks, the server nodes &lt;strong&gt;do not have records of the users&lt;/strong&gt;, &lt;strong&gt;do not communicate with each other&lt;/strong&gt; and &lt;strong&gt;do not store messages&lt;/strong&gt; after they are delivered to the recipients. There is no way to discover the full list of servers participating in SimpleX network. This design avoids the problem of metadata visibility that all federated networks have and better protects from the network-wide attacks.&lt;/p&gt; 
&lt;p&gt;Only the client devices have information about users, their contacts and groups.&lt;/p&gt; 
&lt;p&gt;See &lt;a href=&quot;https://github.com/simplex-chat/simplexmq/raw/stable/protocol/overview-tjr.md&quot;&gt;SimpleX whitepaper&lt;/a&gt; for more information on platform objectives and technical design.&lt;/p&gt; 
&lt;p&gt;See &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/docs/protocol/simplex-chat.md&quot;&gt;SimpleX Chat Protocol&lt;/a&gt; for the format of messages sent between chat clients over &lt;a href=&quot;https://github.com/simplex-chat/simplexmq/raw/stable/protocol/simplex-messaging.md&quot;&gt;SimpleX Messaging Protocol&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;Privacy and security: technical details and limitations&lt;/h2&gt; 
&lt;p&gt;SimpleX Chat is a work in progress – we are releasing improvements as they are ready. You have to decide if the current state is good enough for your usage scenario.&lt;/p&gt; 
&lt;p&gt;We compiled a &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/docs/GLOSSARY.md&quot;&gt;glossary of terms&lt;/a&gt; used to describe communication systems to help understand some terms below and to help compare advantages and disadvantages of various communication systems.&lt;/p&gt; 
&lt;p&gt;What is already implemented:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;Instead of user profile identifiers used by all other platforms, even the most private ones, SimpleX uses &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/docs/GLOSSARY.md#pairwise-pseudonymous-identifier&quot;&gt;pairwise per-queue identifiers&lt;/a&gt; (2 addresses for each unidirectional message queue, with an optional 3rd address for push notifications on iOS, 2 queues in each connection between the users). It makes observing the network graph on the application level more difficult, as for &lt;code&gt;n&lt;/code&gt; users there can be up to &lt;code&gt;n * (n-1)&lt;/code&gt; message queues.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/docs/GLOSSARY.md#end-to-end-encryption&quot;&gt;End-to-end encryption&lt;/a&gt; in each message queue using &lt;a href=&quot;https://nacl.cr.yp.to/box.html&quot;&gt;NaCl cryptobox&lt;/a&gt;. This is added to allow redundancy in the future (passing each message via several servers), to avoid having the same ciphertext in different queues (that would only be visible to the attacker if TLS is compromised). The encryption keys used for this encryption are not rotated, instead we are planning to rotate the queues. Curve25519 keys are used for key negotiation.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/docs/GLOSSARY.md#double-ratchet-algorithm&quot;&gt;Double ratchet&lt;/a&gt; end-to-end encryption in each conversation between two users (or group members). This is the same algorithm that is used in Signal and many other messaging apps; it provides OTR messaging with &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/docs/GLOSSARY.md#forward-secrecy&quot;&gt;forward secrecy&lt;/a&gt; (each message is encrypted by its own ephemeral key) and &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/docs/GLOSSARY.md#post-compromise-security&quot;&gt;break-in recovery&lt;/a&gt; (the keys are frequently re-negotiated as part of the message exchange). Two pairs of Curve448 keys are used for the initial &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/docs/GLOSSARY.md#key-agreement-protocol&quot;&gt;key agreement&lt;/a&gt;, initiating party passes these keys via the connection link, accepting side - in the header of the confirmation message.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/docs/GLOSSARY.md#post-quantum-cryptography&quot;&gt;Post-quantum resistant key exchange&lt;/a&gt; in double ratchet protocol &lt;em&gt;on every ratchet step&lt;/em&gt;. Read more in &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/blog/20240314-simplex-chat-v5-6-quantum-resistance-signal-double-ratchet-algorithm.md&quot;&gt;this post&lt;/a&gt; and also see this &lt;a href=&quot;https://security.apple.com/blog/imessage-pq3/&quot;&gt;publication by Apple&lt;/a&gt; explaining the need for post-quantum key rotation.&lt;/li&gt; 
 &lt;li&gt;Additional layer of encryption using NaCL cryptobox for the messages delivered from the server to the recipient. This layer avoids having any ciphertext in common between sent and received traffic of the server inside TLS (and there are no identifiers in common as well).&lt;/li&gt; 
 &lt;li&gt;Several levels of &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/docs/GLOSSARY.md#message-padding&quot;&gt;content padding&lt;/a&gt; to frustrate message size attacks.&lt;/li&gt; 
 &lt;li&gt;All message metadata, including the time when the message was received by the server (rounded to a second) is sent to the recipients inside an encrypted envelope, so even if TLS is compromised it cannot be observed.&lt;/li&gt; 
 &lt;li&gt;Only TLS 1.2/1.3 are allowed for client-server connections, limited to cryptographic algorithms: CHACHA20POLY1305_SHA256, Ed25519/Ed448, Curve25519/Curve448.&lt;/li&gt; 
 &lt;li&gt;To protect against replay attacks SimpleX servers require &lt;a href=&quot;https://www.rfc-editor.org/rfc/rfc5929.html&quot;&gt;tlsunique channel binding&lt;/a&gt; as session ID in each client command signed with per-queue ephemeral key.&lt;/li&gt; 
 &lt;li&gt;To protect your IP address from unknown messaging relays, and for per-message transport anonymity (compared with Tor/VPN per-connection anonymity), from v6.0 all SimpleX Chat clients use private message routing by default. Read more in &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/blog/20240604-simplex-chat-v5.8-private-message-routing-chat-themes.md#private-message-routing&quot;&gt;this post&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;To protect your IP address from unknown file relays, when SOCKS proxy is not enabled SimpleX Chat clients ask for a confirmation before downloading the files from unknown servers.&lt;/li&gt; 
 &lt;li&gt;To protect your IP address from known servers all SimpleX Chat clients support accessing messaging servers via Tor - see &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/blog/20220808-simplex-chat-v3.1-chat-groups.md&quot;&gt;v3.1 release announcement&lt;/a&gt; for more details.&lt;/li&gt; 
 &lt;li&gt;Local database encryption with passphrase - your contacts, groups and all sent and received messages are stored encrypted. If you used SimpleX Chat before v4.0 you need to enable the encryption via the app settings.&lt;/li&gt; 
 &lt;li&gt;Transport isolation - different TCP connections and Tor circuits are used for traffic of different user profiles, optionally - for different contacts and group member connections.&lt;/li&gt; 
 &lt;li&gt;Manual messaging queue rotations to move conversation to another SMP relay.&lt;/li&gt; 
 &lt;li&gt;Sending end-to-end encrypted files using &lt;a href=&quot;https://simplex.chat/blog/20230301-simplex-file-transfer-protocol.html&quot;&gt;XFTP protocol&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;Local files encryption.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/docs/SERVER.md#reproduce-builds&quot;&gt;Reproducible server builds&lt;/a&gt;.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;We plan to add:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;Automatic message queue rotation and redundancy. Currently the queues created between two users are used until the queue is manually changed by the user or contact is deleted. We are planning to add automatic queue rotation to make these identifiers temporary and rotate based on some schedule TBC (e.g., every X messages, or every X hours/days).&lt;/li&gt; 
 &lt;li&gt;Message &quot;mixing&quot; - adding latency to message delivery, to protect against traffic correlation by message time.&lt;/li&gt; 
 &lt;li&gt;Reproducible clients builds – this is a complex problem, but we are aiming to have it in 2025 at least partially.&lt;/li&gt; 
 &lt;li&gt;Recipients&#39; XFTP relays to reduce traffic and conceal IP addresses from the relays chosen, and potentially controlled, by another party.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;h2&gt;For developers&lt;/h2&gt; 
&lt;p&gt;You can:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/#develop-a-chat-bot&quot;&gt;create chat bots and services&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;run &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/docs/CLI.md&quot;&gt;simplex-chat terminal CLI&lt;/a&gt; to execute individual chat commands, e.g. to send messages as part of shell script execution.&lt;/li&gt; 
 &lt;li&gt;use SimpleX Chat library to integrate chat functionality into your mobile apps.&lt;/li&gt; 
 &lt;li&gt;create chat bots and services in Haskell - see &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/apps/simplex-bot/&quot;&gt;simple&lt;/a&gt; and more &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/apps/simplex-bot-advanced/&quot;&gt;advanced chat bot example&lt;/a&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;If you are considering developing with SimpleX platform please get in touch for any advice and support.&lt;/p&gt; 
&lt;p&gt;Please also join &lt;a href=&quot;https://simplex.chat/contact#/?v=1-2&amp;amp;smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2F6eHqy7uAbZPOcA6qBtrQgQquVlt4Ll91%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAqV_pg3FF00L98aCXp4D3bOs4Sxv_UmSd-gb0juVoQVs%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion&amp;amp;data=%7B%22type%22%3A%22group%22%2C%22groupLinkId%22%3A%22XonlixcHBIb2ijCehbZoiw%3D%3D%22%7D&quot;&gt;#simplex-devs&lt;/a&gt; group to ask any questions and share your success stories.&lt;/p&gt; 
&lt;h2&gt;Develop a chat bot&lt;/h2&gt; 
&lt;p&gt;You can create a chat bot or any chat-based service in any language running SimpleX Chat terminal CLI as a local WebSocket server.&lt;/p&gt; 
&lt;p&gt;See &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/bots/README.md&quot;&gt;our new bot API reference&lt;/a&gt;. Most of it is automatically generated from core library types, so it stays up to date.&lt;/p&gt; 
&lt;p&gt;Also see &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/packages/simplex-chat-client/&quot;&gt;TypeScript SimpleX Chat client&lt;/a&gt; and &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/packages/simplex-chat-client/typescript/examples/squaring-bot.js&quot;&gt;JavaScript chat bot example&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;Roadmap&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;✅ Easy to deploy SimpleX server with in-memory message storage, without any dependencies.&lt;/li&gt; 
 &lt;li&gt;✅ Terminal (console) client with groups and files support.&lt;/li&gt; 
 &lt;li&gt;✅ One-click SimpleX server deployment on Linode.&lt;/li&gt; 
 &lt;li&gt;✅ End-to-end encryption using double-ratchet protocol with additional encryption layer.&lt;/li&gt; 
 &lt;li&gt;✅ Mobile apps v1 for Android and iOS.&lt;/li&gt; 
 &lt;li&gt;✅ Private instant notifications for Android using background service.&lt;/li&gt; 
 &lt;li&gt;✅ Haskell chat bot templates.&lt;/li&gt; 
 &lt;li&gt;✅ v2.0 - supporting images and files in mobile apps.&lt;/li&gt; 
 &lt;li&gt;✅ Manual chat history deletion.&lt;/li&gt; 
 &lt;li&gt;✅ End-to-end encrypted WebRTC audio and video calls via the mobile apps.&lt;/li&gt; 
 &lt;li&gt;✅ Privacy preserving instant notifications for iOS using Apple Push Notification service.&lt;/li&gt; 
 &lt;li&gt;✅ Chat database export and import.&lt;/li&gt; 
 &lt;li&gt;✅ Chat groups in mobile apps.&lt;/li&gt; 
 &lt;li&gt;✅ Connecting to messaging servers via Tor.&lt;/li&gt; 
 &lt;li&gt;✅ Dual server addresses to access messaging servers as v3 hidden services.&lt;/li&gt; 
 &lt;li&gt;✅ Chat server and TypeScript client SDK to develop chat interfaces, integrations and chat bots (ready for announcement).&lt;/li&gt; 
 &lt;li&gt;✅ Incognito mode to share a new random name with each contact.&lt;/li&gt; 
 &lt;li&gt;✅ Chat database encryption.&lt;/li&gt; 
 &lt;li&gt;✅ Automatic chat history deletion.&lt;/li&gt; 
 &lt;li&gt;✅ Links to join groups and improve groups stability.&lt;/li&gt; 
 &lt;li&gt;✅ Voice messages (with recipient opt-out per contact).&lt;/li&gt; 
 &lt;li&gt;✅ Basic authentication for SMP servers (to authorize creating new queues).&lt;/li&gt; 
 &lt;li&gt;✅ View deleted messages, full message deletion by sender (with recipient opt-in per contact).&lt;/li&gt; 
 &lt;li&gt;✅ Block screenshots and view in recent apps.&lt;/li&gt; 
 &lt;li&gt;✅ Advanced server configuration.&lt;/li&gt; 
 &lt;li&gt;✅ Disappearing messages (with recipient opt-in per-contact).&lt;/li&gt; 
 &lt;li&gt;✅ &quot;Live&quot; messages.&lt;/li&gt; 
 &lt;li&gt;✅ Contact verification via a separate out-of-band channel.&lt;/li&gt; 
 &lt;li&gt;✅ Multiple user profiles in the same chat database.&lt;/li&gt; 
 &lt;li&gt;✅ Optionally avoid re-using the same TCP session for multiple connections.&lt;/li&gt; 
 &lt;li&gt;✅ Preserve message drafts.&lt;/li&gt; 
 &lt;li&gt;✅ File server to optimize for efficient and private sending of large files.&lt;/li&gt; 
 &lt;li&gt;✅ Improved audio &amp;amp; video calls.&lt;/li&gt; 
 &lt;li&gt;✅ Support older Android OS and 32-bit CPUs.&lt;/li&gt; 
 &lt;li&gt;✅ Hidden chat profiles.&lt;/li&gt; 
 &lt;li&gt;✅ Sending and receiving large files via &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/blog/20230301-simplex-file-transfer-protocol.md&quot;&gt;XFTP protocol&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;✅ Video messages.&lt;/li&gt; 
 &lt;li&gt;✅ App access passcode.&lt;/li&gt; 
 &lt;li&gt;✅ Improved Android app UI design.&lt;/li&gt; 
 &lt;li&gt;✅ Optional alternative access password.&lt;/li&gt; 
 &lt;li&gt;✅ Message reactions&lt;/li&gt; 
 &lt;li&gt;✅ Message editing history&lt;/li&gt; 
 &lt;li&gt;✅ Reduced battery and traffic usage in large groups.&lt;/li&gt; 
 &lt;li&gt;✅ Message delivery confirmation (with sender opt-out per contact).&lt;/li&gt; 
 &lt;li&gt;✅ Desktop client.&lt;/li&gt; 
 &lt;li&gt;✅ Encryption of local files stored in the app.&lt;/li&gt; 
 &lt;li&gt;✅ Using mobile profiles from the desktop app.&lt;/li&gt; 
 &lt;li&gt;✅ Private notes.&lt;/li&gt; 
 &lt;li&gt;✅ Improve sending videos (including encryption of locally stored videos).&lt;/li&gt; 
 &lt;li&gt;✅ Post-quantum resistant key exchange in double ratchet protocol.&lt;/li&gt; 
 &lt;li&gt;✅ Message delivery relay for senders (to conceal IP address from the recipients&#39; servers and to reduce the traffic).&lt;/li&gt; 
 &lt;li&gt;✅ Support multiple network operators in the app.&lt;/li&gt; 
 &lt;li&gt;🏗 Large groups, communities and public channels.&lt;/li&gt; 
 &lt;li&gt;🏗 Short links to connect and join groups.&lt;/li&gt; 
 &lt;li&gt;🏗 Improve stability and reduce battery usage.&lt;/li&gt; 
 &lt;li&gt;🏗 Improve experience for the new users.&lt;/li&gt; 
 &lt;li&gt;Privacy &amp;amp; security slider - a simple way to set all settings at once.&lt;/li&gt; 
 &lt;li&gt;SMP queue redundancy and rotation (manual is supported).&lt;/li&gt; 
 &lt;li&gt;Include optional message into connection request sent via contact address.&lt;/li&gt; 
 &lt;li&gt;Improved navigation and search in the conversation (expand and scroll to quoted message, scroll to search results, etc.).&lt;/li&gt; 
 &lt;li&gt;Feeds/broadcasts.&lt;/li&gt; 
 &lt;li&gt;Ephemeral/disappearing/OTR conversations with the existing contacts.&lt;/li&gt; 
 &lt;li&gt;Privately share your location.&lt;/li&gt; 
 &lt;li&gt;Web widgets for custom interactivity in the chats.&lt;/li&gt; 
 &lt;li&gt;Programmable chat automations / rules (automatic replies/forward/deletion/sending, reminders, etc.).&lt;/li&gt; 
 &lt;li&gt;Privacy-preserving identity server for optional DNS-based contact/group addresses to simplify connection and discovery, but not used to deliver messages: 
  &lt;ul&gt; 
   &lt;li&gt;keep all your contacts and groups even if you lose the domain.&lt;/li&gt; 
   &lt;li&gt;the server doesn&#39;t have information about your contacts and groups.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;High capacity multi-node SMP relays.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Disclaimers&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/simplex-chat/simplexmq/raw/master/protocol/overview-tjr.md&quot;&gt;SimpleX protocols and security model&lt;/a&gt; was reviewed, and had many breaking changes and improvements in v1.0.0.&lt;/p&gt; 
&lt;p&gt;The implementation security assessment of SimpleX cryptography and networking was done in October 2022 by &lt;a href=&quot;https://www.trailofbits.com/about&quot;&gt;Trail of Bits&lt;/a&gt; – see &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/blog/20221108-simplex-chat-v4.2-security-audit-new-website.md&quot;&gt;the announcement&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;The cryptographic review of SimpleX protocols was done in July 2024 by Trail of Bits – see &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/blog/20241014-simplex-network-v6-1-security-review-better-calls-user-experience.md&quot;&gt;the announcement&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;SimpleX Chat is still a relatively early stage platform (the mobile apps were released in March 2022), so you may discover some bugs and missing features. We would really appreciate if you let us know anything that needs to be fixed or improved.&lt;/p&gt; 
&lt;p&gt;The default servers configured in the app are provided on the best effort basis. We are currently not guaranteeing any SLAs, although historically our servers had over 99.9% uptime each.&lt;/p&gt; 
&lt;p&gt;We have never provided or have been requested access to our servers or any information from our servers by any third parties. If we are ever requested to provide such access or information, we will be following due legal process.&lt;/p&gt; 
&lt;p&gt;We do not log IP addresses of the users and we do not perform any traffic correlation on our servers. If transport level security is critical you must use Tor or some other similar network to access messaging servers. We will be improving the client applications to reduce the opportunities for traffic correlation.&lt;/p&gt; 
&lt;p&gt;Please read more in &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/PRIVACY.md&quot;&gt;Privacy Policy&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;Security contact&lt;/h2&gt; 
&lt;p&gt;Please see our &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/docs/SECURITY.md&quot;&gt;Security Policy&lt;/a&gt; on how to report security vulnerabilities to us. We will coordinate the fix and disclosure.&lt;/p&gt; 
&lt;p&gt;Please do NOT report security vulnerabilities via GitHub issues.&lt;/p&gt; 
&lt;h2&gt;License&lt;/h2&gt; 
&lt;p&gt;This software is licensed under the GNU Affero General Public License version 3 (AGPLv3). See the &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/LICENSE&quot;&gt;LICENSE&lt;/a&gt; file for details. The SimpleX and SimpleX Chat name, logo, associated branding materials, and application and website graphic assets (illustrations, images, visual designs, etc.) are not covered by this license and are subject to the terms outlined in the &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/docs/TRADEMARK.md&quot;&gt;TRADEMARK&lt;/a&gt; and &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/assets/ASSETS_LICENSE.md&quot;&gt;ASSETS_LICENSE&lt;/a&gt; files respectively.&lt;/p&gt; 
&lt;p&gt;If you want to use any graphic assets in your publications, please ask for permission. Texts can be used as direct quotes, referencing the source.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://apps.apple.com/us/app/simplex-chat/id1605771084&quot;&gt;&lt;img src=&quot;https://raw.githubusercontent.com/simplex-chat/.github/refs/heads/master/profile/images/apple_store.svg?sanitize=true&quot; alt=&quot;iOS app&quot; height=&quot;42&quot; /&gt;&lt;/a&gt; &amp;nbsp; &lt;a href=&quot;https://play.google.com/store/apps/details?id=chat.simplex.app&quot;&gt;&lt;img src=&quot;https://raw.githubusercontent.com/simplex-chat/.github/refs/heads/master/profile/images/google_play.svg?sanitize=true&quot; alt=&quot;Android app&quot; /&gt;&lt;/a&gt; &amp;nbsp; &lt;a href=&quot;https://app.simplex.chat&quot;&gt;&lt;img src=&quot;https://raw.githubusercontent.com/simplex-chat/.github/refs/heads/master/profile/images/f_droid.svg?sanitize=true&quot; alt=&quot;F-Droid&quot; height=&quot;41&quot; /&gt;&lt;/a&gt; &amp;nbsp; &lt;a href=&quot;https://testflight.apple.com/join/DWuT2LQu&quot;&gt;&lt;img src=&quot;https://raw.githubusercontent.com/simplex-chat/.github/refs/heads/master/profile/images/testflight.png&quot; alt=&quot;iOS TestFlight&quot; height=&quot;41&quot; /&gt;&lt;/a&gt; &amp;nbsp; &lt;a href=&quot;https://github.com/simplex-chat/simplex-chat/releases/latest/download/simplex-aarch64.apk&quot;&gt;&lt;img src=&quot;https://raw.githubusercontent.com/simplex-chat/.github/refs/heads/master/profile/images/apk_icon.png&quot; alt=&quot;APK&quot; height=&quot;41&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</description>
      
      <media:content url="https://opengraph.githubassets.com/c28dac7896a172e25c2f5d3c373daa371383a669dcc65aa21b7a72170684569c/simplex-chat/simplex-chat" medium="image" />
      
    </item>
    
    <item>
      <title>koalaman/shellcheck</title>
      <link>https://github.com/koalaman/shellcheck</link>
      <description>&lt;p&gt;ShellCheck, a static analysis tool for shell scripts&lt;/p&gt;&lt;hr&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/actions/workflows/build.yml&quot;&gt;&lt;img src=&quot;https://github.com/koalaman/shellcheck/actions/workflows/build.yml/badge.svg?sanitize=true&quot; alt=&quot;Build Status&quot; /&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;h1&gt;ShellCheck - A shell script static analysis tool&lt;/h1&gt; 
&lt;p&gt;ShellCheck is a GPLv3 tool that gives warnings and suggestions for bash/sh shell scripts:&lt;/p&gt; 
&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/koalaman/shellcheck/master/doc/terminal.png&quot; alt=&quot;Screenshot of a terminal showing problematic shell script lines highlighted&quot; /&gt;&lt;/p&gt; 
&lt;p&gt;The goals of ShellCheck are&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;To point out and clarify typical beginner&#39;s syntax issues that cause a shell to give cryptic error messages.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;To point out and clarify typical intermediate level semantic problems that cause a shell to behave strangely and counter-intuitively.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;To point out subtle caveats, corner cases and pitfalls that may cause an advanced user&#39;s otherwise working script to fail under future circumstances.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;See &lt;a href=&quot;https://raw.githubusercontent.com/koalaman/shellcheck/master/README.md#user-content-gallery-of-bad-code&quot;&gt;the gallery of bad code&lt;/a&gt; for examples of what ShellCheck can help you identify!&lt;/p&gt; 
&lt;h2&gt;Table of Contents&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/koalaman/shellcheck/master/#how-to-use&quot;&gt;How to use&lt;/a&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/koalaman/shellcheck/master/#on-the-web&quot;&gt;On the web&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/koalaman/shellcheck/master/#from-your-terminal&quot;&gt;From your terminal&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/koalaman/shellcheck/master/#in-your-editor&quot;&gt;In your editor&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/koalaman/shellcheck/master/#in-your-build-or-test-suites&quot;&gt;In your build or test suites&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/koalaman/shellcheck/master/#installing&quot;&gt;Installing&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/koalaman/shellcheck/master/#compiling-from-source&quot;&gt;Compiling from source&lt;/a&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/koalaman/shellcheck/master/#installing-cabal&quot;&gt;Installing Cabal&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/koalaman/shellcheck/master/#compiling-shellcheck&quot;&gt;Compiling ShellCheck&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/koalaman/shellcheck/master/#running-tests&quot;&gt;Running tests&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/koalaman/shellcheck/master/#gallery-of-bad-code&quot;&gt;Gallery of bad code&lt;/a&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/koalaman/shellcheck/master/#quoting&quot;&gt;Quoting&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/koalaman/shellcheck/master/#conditionals&quot;&gt;Conditionals&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/koalaman/shellcheck/master/#frequently-misused-commands&quot;&gt;Frequently misused commands&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/koalaman/shellcheck/master/#common-beginners-mistakes&quot;&gt;Common beginner&#39;s mistakes&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/koalaman/shellcheck/master/#style&quot;&gt;Style&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/koalaman/shellcheck/master/#data-and-typing-errors&quot;&gt;Data and typing errors&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/koalaman/shellcheck/master/#robustness&quot;&gt;Robustness&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/koalaman/shellcheck/master/#portability&quot;&gt;Portability&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/koalaman/shellcheck/master/#miscellaneous&quot;&gt;Miscellaneous&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/koalaman/shellcheck/master/#testimonials&quot;&gt;Testimonials&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/koalaman/shellcheck/master/#ignoring-issues&quot;&gt;Ignoring issues&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/koalaman/shellcheck/master/#reporting-bugs&quot;&gt;Reporting bugs&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/koalaman/shellcheck/master/#contributing&quot;&gt;Contributing&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/koalaman/shellcheck/master/#copyright&quot;&gt;Copyright&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/koalaman/shellcheck/master/#other-resources&quot;&gt;Other Resources&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;How to use&lt;/h2&gt; 
&lt;p&gt;There are a number of ways to use ShellCheck!&lt;/p&gt; 
&lt;h3&gt;On the web&lt;/h3&gt; 
&lt;p&gt;Paste a shell script on &lt;a href=&quot;https://www.shellcheck.net&quot;&gt;https://www.shellcheck.net&lt;/a&gt; for instant feedback.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.shellcheck.net&quot;&gt;ShellCheck.net&lt;/a&gt; is always synchronized to the latest git commit, and is the easiest way to give ShellCheck a go. Tell your friends!&lt;/p&gt; 
&lt;h3&gt;From your terminal&lt;/h3&gt; 
&lt;p&gt;Run &lt;code&gt;shellcheck yourscript&lt;/code&gt; in your terminal for instant output, as seen above.&lt;/p&gt; 
&lt;h3&gt;In your editor&lt;/h3&gt; 
&lt;p&gt;You can see ShellCheck suggestions directly in a variety of editors.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Vim, through &lt;a href=&quot;https://github.com/w0rp/ale&quot;&gt;ALE&lt;/a&gt;, &lt;a href=&quot;https://github.com/neomake/neomake&quot;&gt;Neomake&lt;/a&gt;, or &lt;a href=&quot;https://github.com/scrooloose/syntastic&quot;&gt;Syntastic&lt;/a&gt;:&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/koalaman/shellcheck/master/doc/vim-syntastic.png&quot; alt=&quot;Screenshot of Vim showing inlined shellcheck feedback&quot; /&gt;.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Emacs, through &lt;a href=&quot;https://github.com/flycheck/flycheck&quot;&gt;Flycheck&lt;/a&gt; or &lt;a href=&quot;https://github.com/federicotdn/flymake-shellcheck&quot;&gt;Flymake&lt;/a&gt;:&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/koalaman/shellcheck/master/doc/emacs-flycheck.png&quot; alt=&quot;Screenshot of emacs showing inlined shellcheck feedback&quot; /&gt;.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;Sublime, through &lt;a href=&quot;https://github.com/SublimeLinter/SublimeLinter-shellcheck&quot;&gt;SublimeLinter&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Pulsar Edit (former Atom), through &lt;a href=&quot;https://github.com/pulsar-cooperative/linter-shellcheck-pulsar&quot;&gt;linter-shellcheck-pulsar&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;VSCode, through &lt;a href=&quot;https://github.com/timonwong/vscode-shellcheck&quot;&gt;vscode-shellcheck&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Most other editors, through &lt;a href=&quot;https://raw.githubusercontent.com/koalaman/shellcheck/master/shellcheck.1.md#user-content-formats&quot;&gt;GCC error compatibility&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;In your build or test suites&lt;/h3&gt; 
&lt;p&gt;While ShellCheck is mostly intended for interactive use, it can easily be added to builds or test suites. It makes canonical use of exit codes, so you can just add a &lt;code&gt;shellcheck&lt;/code&gt; command as part of the process.&lt;/p&gt; 
&lt;p&gt;For example, in a Makefile:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-Makefile&quot;&gt;check-scripts:
    # Fail if any of these files have warnings
    shellcheck myscripts/*.sh
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;or in a Travis CI &lt;code&gt;.travis.yml&lt;/code&gt; file:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;script:
  # Fail if any of these files have warnings
  - shellcheck myscripts/*.sh
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Services and platforms that have ShellCheck pre-installed and ready to use:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://travis-ci.org/&quot;&gt;Travis CI&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.codacy.com/&quot;&gt;Codacy&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://codeclimate.com/&quot;&gt;Code Climate&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.codefactor.io/&quot;&gt;Code Factor&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.codety.io/&quot;&gt;Codety&lt;/a&gt; via the &lt;a href=&quot;https://github.com/codetyio/codety-scanner&quot;&gt;Codety Scanner&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://circleci.com&quot;&gt;CircleCI&lt;/a&gt; via the &lt;a href=&quot;https://circleci.com/orbs/registry/orb/circleci/shellcheck&quot;&gt;ShellCheck Orb&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/features/actions&quot;&gt;Github&lt;/a&gt; (only Linux)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://trunk.io/code-quality&quot;&gt;Trunk Code Quality&lt;/a&gt; (universal linter; &lt;a href=&quot;https://github.com/trunk-io/plugins/raw/bcbb361dcdbe4619af51ea7db474d7fb87540d20/.trunk/trunk.yaml#L32&quot;&gt;allows you to explicitly version your shellcheck install&lt;/a&gt;) via the &lt;a href=&quot;https://github.com/trunk-io/plugins/raw/main/linters/shellcheck/plugin.yaml&quot;&gt;shellcheck plugin&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://coderabbit.ai/&quot;&gt;CodeRabbit&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Most other services, including &lt;a href=&quot;https://about.gitlab.com/&quot;&gt;GitLab&lt;/a&gt;, let you install ShellCheck yourself, either through the system&#39;s package manager (see &lt;a href=&quot;https://raw.githubusercontent.com/koalaman/shellcheck/master/#installing&quot;&gt;Installing&lt;/a&gt;), or by downloading and unpacking a &lt;a href=&quot;https://raw.githubusercontent.com/koalaman/shellcheck/master/#installing-a-pre-compiled-binary&quot;&gt;binary release&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;It&#39;s a good idea to manually install a specific ShellCheck version regardless. This avoids any surprise build breaks when a new version with new warnings is published.&lt;/p&gt; 
&lt;p&gt;For customized filtering or reporting, ShellCheck can output simple JSON, CheckStyle compatible XML, GCC compatible warnings as well as human readable text (with or without ANSI colors). See the &lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/Integration&quot;&gt;Integration&lt;/a&gt; wiki page for more documentation.&lt;/p&gt; 
&lt;h2&gt;Installing&lt;/h2&gt; 
&lt;p&gt;The easiest way to install ShellCheck locally is through your package manager.&lt;/p&gt; 
&lt;p&gt;On systems with Cabal (installs to &lt;code&gt;~/.cabal/bin&lt;/code&gt;):&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;cabal update
cabal install ShellCheck
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;On systems with Stack (installs to &lt;code&gt;~/.local/bin&lt;/code&gt;):&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;stack update
stack install ShellCheck
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;On Debian based distros:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;sudo apt install shellcheck
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;On Arch Linux based distros:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;pacman -S shellcheck
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;or get the dependency free &lt;a href=&quot;https://aur.archlinux.org/packages/shellcheck-bin/&quot;&gt;shellcheck-bin&lt;/a&gt; from the AUR.&lt;/p&gt; 
&lt;p&gt;On Gentoo based distros:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;emerge --ask shellcheck
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;On EPEL based distros:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;sudo yum -y install epel-release
sudo yum install ShellCheck
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;On Fedora based distros:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;dnf install ShellCheck
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;On FreeBSD:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;pkg install hs-ShellCheck
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;On macOS (OS X) with Homebrew:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;brew install shellcheck
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Or with MacPorts:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;sudo port install shellcheck
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;On OpenBSD:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;pkg_add shellcheck
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;On openSUSE&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;zypper in ShellCheck
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Or use OneClickInstall - &lt;a href=&quot;https://software.opensuse.org/package/ShellCheck&quot;&gt;https://software.opensuse.org/package/ShellCheck&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;On Solus:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;eopkg install shellcheck
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;On Windows (via &lt;a href=&quot;https://chocolatey.org/packages/shellcheck&quot;&gt;chocolatey&lt;/a&gt;):&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-cmd&quot;&gt;C:\&amp;gt; choco install shellcheck
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Or Windows (via &lt;a href=&quot;https://github.com/microsoft/winget-pkgs&quot;&gt;winget&lt;/a&gt;):&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-cmd&quot;&gt;C:\&amp;gt; winget install --id koalaman.shellcheck
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Or Windows (via &lt;a href=&quot;http://scoop.sh&quot;&gt;scoop&lt;/a&gt;):&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-cmd&quot;&gt;C:\&amp;gt; scoop install shellcheck
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;From &lt;a href=&quot;https://anaconda.org/conda-forge/shellcheck&quot;&gt;conda-forge&lt;/a&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;conda install -c conda-forge shellcheck
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;From Snap Store:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;snap install --channel=edge shellcheck
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;From Docker Hub:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;docker run --rm -v &quot;$PWD:/mnt&quot; koalaman/shellcheck:stable myscript
# Or :v0.4.7 for that version, or :latest for daily builds
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;or use &lt;code&gt;koalaman/shellcheck-alpine&lt;/code&gt; if you want a larger Alpine Linux based image to extend. It works exactly like a regular Alpine image, but has shellcheck preinstalled.&lt;/p&gt; 
&lt;p&gt;Using the &lt;a href=&quot;https://nixos.org/nix&quot;&gt;nix package manager&lt;/a&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;nix-env -iA nixpkgs.shellcheck
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Using the &lt;a href=&quot;https://flox.dev/&quot;&gt;Flox package manager&lt;/a&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;flox install shellcheck
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Alternatively, you can download pre-compiled binaries for the latest release here:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/releases/download/stable/shellcheck-stable.linux.x86_64.tar.xz&quot;&gt;Linux, x86_64&lt;/a&gt; (statically linked)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/releases/download/stable/shellcheck-stable.linux.armv6hf.tar.xz&quot;&gt;Linux, armv6hf&lt;/a&gt;, i.e. Raspberry Pi (statically linked)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/releases/download/stable/shellcheck-stable.linux.aarch64.tar.xz&quot;&gt;Linux, aarch64&lt;/a&gt; aka ARM64 (statically linked)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/releases/download/stable/shellcheck-stable.darwin.aarch64.tar.xz&quot;&gt;macOS, aarch64&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/releases/download/stable/shellcheck-stable.darwin.x86_64.tar.xz&quot;&gt;macOS, x86_64&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/releases/download/stable/shellcheck-stable.zip&quot;&gt;Windows, x86&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;or see the &lt;a href=&quot;https://github.com/koalaman/shellcheck/releases&quot;&gt;GitHub Releases&lt;/a&gt; for other releases (including the &lt;a href=&quot;https://github.com/koalaman/shellcheck/releases/tag/latest&quot;&gt;latest&lt;/a&gt; meta-release for daily git builds).&lt;/p&gt; 
&lt;p&gt;There are currently no official binaries for Apple Silicon, but third party builds are available via &lt;a href=&quot;https://github.com/vscode-shellcheck/shellcheck-binaries/releases&quot;&gt;ShellCheck for Visual Studio Code&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;Distro packages already come with a &lt;code&gt;man&lt;/code&gt; page. If you are building from source, it can be installed with:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-console&quot;&gt;pandoc -s -f markdown-smart -t man shellcheck.1.md -o shellcheck.1
sudo mv shellcheck.1 /usr/share/man/man1
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;pre-commit&lt;/h3&gt; 
&lt;p&gt;To run ShellCheck via &lt;a href=&quot;https://pre-commit.com/&quot;&gt;pre-commit&lt;/a&gt;, add the hook to your &lt;code&gt;.pre-commit-config.yaml&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;repos:
-   repo: https://github.com/koalaman/shellcheck-precommit
    rev: v0.11.0
    hooks:
    -   id: shellcheck
#       args: [&quot;--severity=warning&quot;]  # Optionally only show errors and warnings
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Travis CI&lt;/h3&gt; 
&lt;p&gt;Travis CI has now integrated ShellCheck by default, so you don&#39;t need to manually install it.&lt;/p&gt; 
&lt;p&gt;If you still want to do so in order to upgrade at your leisure or ensure you&#39;re using the latest release, follow the steps below to install a binary version.&lt;/p&gt; 
&lt;h3&gt;Installing a pre-compiled binary&lt;/h3&gt; 
&lt;p&gt;The pre-compiled binaries come in &lt;code&gt;tar.xz&lt;/code&gt; files. To decompress them, make sure &lt;code&gt;xz&lt;/code&gt; is installed. On Debian/Ubuntu/Mint, you can &lt;code&gt;apt install xz-utils&lt;/code&gt;. On Redhat/Fedora/CentOS, &lt;code&gt;yum -y install xz&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;A simple installer may do something like:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;scversion=&quot;stable&quot; # or &quot;v0.4.7&quot;, or &quot;latest&quot;
wget -qO- &quot;https://github.com/koalaman/shellcheck/releases/download/${scversion?}/shellcheck-${scversion?}.linux.x86_64.tar.xz&quot; | tar -xJv
cp &quot;shellcheck-${scversion}/shellcheck&quot; /usr/bin/
shellcheck --version
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Compiling from source&lt;/h2&gt; 
&lt;p&gt;This section describes how to build ShellCheck from a source directory. ShellCheck is written in Haskell and requires 2GB of RAM to compile.&lt;/p&gt; 
&lt;h3&gt;Installing Cabal&lt;/h3&gt; 
&lt;p&gt;ShellCheck is built and packaged using Cabal. Install the package &lt;code&gt;cabal-install&lt;/code&gt; from your system&#39;s package manager (with e.g. &lt;code&gt;apt-get&lt;/code&gt;, &lt;code&gt;brew&lt;/code&gt;, &lt;code&gt;emerge&lt;/code&gt;, &lt;code&gt;yum&lt;/code&gt;, or &lt;code&gt;zypper&lt;/code&gt;).&lt;/p&gt; 
&lt;p&gt;On macOS (OS X), you can do a fast install of Cabal using brew, which takes a couple of minutes instead of more than 30 minutes if you try to compile it from source.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;$ brew install cabal-install
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;On MacPorts, the package is instead called &lt;code&gt;hs-cabal-install&lt;/code&gt;, while native Windows users should install the latest version of the Haskell platform from &lt;a href=&quot;https://www.haskell.org/platform/&quot;&gt;https://www.haskell.org/platform/&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Verify that &lt;code&gt;cabal&lt;/code&gt; is installed and update its dependency list with&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;$ cabal update
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Compiling ShellCheck&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;git clone&lt;/code&gt; this repository, and &lt;code&gt;cd&lt;/code&gt; to the ShellCheck source directory to build/install:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;$ cabal install
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This will compile ShellCheck and install it to your &lt;code&gt;~/.cabal/bin&lt;/code&gt; directory.&lt;/p&gt; 
&lt;p&gt;Add this directory to your &lt;code&gt;PATH&lt;/code&gt; (for bash, add this to your &lt;code&gt;~/.bashrc&lt;/code&gt;):&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;export PATH=&quot;$HOME/.cabal/bin:$PATH&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Log out and in again, and verify that your PATH is set up correctly:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;$ which shellcheck
~/.cabal/bin/shellcheck
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;On native Windows, the &lt;code&gt;PATH&lt;/code&gt; should already be set up, but the system may use a legacy codepage. In &lt;code&gt;cmd.exe&lt;/code&gt;, &lt;code&gt;powershell.exe&lt;/code&gt; and Powershell ISE, make sure to use a TrueType font, not a Raster font, and set the active codepage to UTF-8 (65001) with &lt;code&gt;chcp&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-cmd&quot;&gt;chcp 65001
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;In Powershell ISE, you may need to additionally update the output encoding:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Running tests&lt;/h3&gt; 
&lt;p&gt;To run the unit test suite:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;$ cabal test
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Gallery of bad code&lt;/h2&gt; 
&lt;p&gt;So what kind of things does ShellCheck look for? Here is an incomplete list of detected issues.&lt;/p&gt; 
&lt;h3&gt;Quoting&lt;/h3&gt; 
&lt;p&gt;ShellCheck can recognize several types of incorrect quoting:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;echo $1                           # Unquoted variables
find . -name *.ogg                # Unquoted find/grep patterns
rm &quot;~/my file.txt&quot;                # Quoted tilde expansion
v=&#39;--verbose=&quot;true&quot;&#39;; cmd $v      # Literal quotes in variables
for f in &quot;*.ogg&quot;                  # Incorrectly quoted &#39;for&#39; loops
touch $@                          # Unquoted $@
echo &#39;Don&#39;t forget to restart!&#39;   # Singlequote closed by apostrophe
echo &#39;Don\&#39;t try this at home&#39;    # Attempting to escape &#39; in &#39;&#39;
echo &#39;Path is $PATH&#39;              # Variables in single quotes
trap &quot;echo Took ${SECONDS}s&quot; 0    # Prematurely expanded trap
unset var[i]                      # Array index treated as glob
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Conditionals&lt;/h3&gt; 
&lt;p&gt;ShellCheck can recognize many types of incorrect test statements.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;[[ n != 0 ]]                      # Constant test expressions
[[ -e *.mpg ]]                    # Existence checks of globs
[[ $foo==0 ]]                     # Always true due to missing spaces
[[ -n &quot;$foo &quot; ]]                  # Always true due to literals
[[ $foo =~ &quot;fo+&quot; ]]               # Quoted regex in =~
[ foo =~ re ]                     # Unsupported [ ] operators
[ $1 -eq &quot;shellcheck&quot; ]           # Numerical comparison of strings
[ $n &amp;amp;&amp;amp; $m ]                      # &amp;amp;&amp;amp; in [ .. ]
[ grep -q foo file ]              # Command without $(..)
[[ &quot;$$file&quot; == *.jpg ]]           # Comparisons that can&#39;t succeed
(( 1 -lt 2 ))                     # Using test operators in ((..))
[ x ] &amp;amp; [ y ] | [ z ]             # Accidental backgrounding and piping
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Frequently misused commands&lt;/h3&gt; 
&lt;p&gt;ShellCheck can recognize instances where commands are used incorrectly:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;grep &#39;*foo*&#39; file                 # Globs in regex contexts
find . -exec foo {} &amp;amp;&amp;amp; bar {} \;  # Prematurely terminated find -exec
sudo echo &#39;Var=42&#39; &amp;gt; /etc/profile # Redirecting sudo
time --format=%s sleep 10         # Passing time(1) flags to time builtin
while read h; do ssh &quot;$h&quot; uptime  # Commands eating while loop input
alias archive=&#39;mv $1 /backup&#39;     # Defining aliases with arguments
tr -cd &#39;[a-zA-Z0-9]&#39;              # [] around ranges in tr
exec foo; echo &quot;Done!&quot;            # Misused &#39;exec&#39;
find -name \*.bak -o -name \*~ -delete  # Implicit precedence in find
# find . -exec foo &amp;gt; bar \;       # Redirections in find
f() { whoami; }; sudo f           # External use of internal functions
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Common beginner&#39;s mistakes&lt;/h3&gt; 
&lt;p&gt;ShellCheck recognizes many common beginner&#39;s syntax errors:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;var = 42                          # Spaces around = in assignments
$foo=42                           # $ in assignments
for $var in *; do ...             # $ in for loop variables
var$n=&quot;Hello&quot;                     # Wrong indirect assignment
echo ${var$n}                     # Wrong indirect reference
var=(1, 2, 3)                     # Comma separated arrays
array=( [index] = value )         # Incorrect index initialization
echo $var[14]                     # Missing {} in array references
echo &quot;Argument 10 is $10&quot;         # Positional parameter misreference
if $(myfunction); then ..; fi     # Wrapping commands in $()
else if othercondition; then ..   # Using &#39;else if&#39;
f; f() { echo &quot;hello world; }     # Using function before definition
[ false ]                         # &#39;false&#39; being true
if ( -f file )                    # Using (..) instead of test
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Style&lt;/h3&gt; 
&lt;p&gt;ShellCheck can make suggestions to improve style:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;[[ -z $(find /tmp | grep mpg) ]]  # Use grep -q instead
a &amp;gt;&amp;gt; log; b &amp;gt;&amp;gt; log; c &amp;gt;&amp;gt; log      # Use a redirection block instead
echo &quot;The time is `date`&quot;         # Use $() instead
cd dir; process *; cd ..;         # Use subshells instead
echo $[1+2]                       # Use standard $((..)) instead of old $[]
echo $(($RANDOM % 6))             # Don&#39;t use $ on variables in $((..))
echo &quot;$(date)&quot;                    # Useless use of echo
cat file | grep foo               # Useless use of cat
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Data and typing errors&lt;/h3&gt; 
&lt;p&gt;ShellCheck can recognize issues related to data and typing:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;args=&quot;$@&quot;                         # Assigning arrays to strings
files=(foo bar); echo &quot;$files&quot;    # Referencing arrays as strings
declare -A arr=(foo bar)          # Associative arrays without index
printf &quot;%s\n&quot; &quot;Arguments: $@.&quot;    # Concatenating strings and arrays
[[ $# &amp;gt; 2 ]]                      # Comparing numbers as strings
var=World; echo &quot;Hello &quot; var      # Unused lowercase variables
echo &quot;Hello $name&quot;                # Unassigned lowercase variables
cmd | read bar; echo $bar         # Assignments in subshells
cat foo | cp bar                  # Piping to commands that don&#39;t read
printf &#39;%s: %s\n&#39; foo             # Mismatches in printf argument count
eval &quot;${array[@]}&quot;                # Lost word boundaries in array eval
for i in &quot;${x[@]}&quot;; do ${x[$i]}   # Using array value as key
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Robustness&lt;/h3&gt; 
&lt;p&gt;ShellCheck can make suggestions for improving the robustness of a script:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;rm -rf &quot;$STEAMROOT/&quot;*            # Catastrophic rm
touch ./-l; ls *                 # Globs that could become options
find . -exec sh -c &#39;a &amp;amp;&amp;amp; b {}&#39; \; # Find -exec shell injection
printf &quot;Hello $name&quot;             # Variables in printf format
for f in $(ls *.txt); do         # Iterating over ls output
export MYVAR=$(cmd)              # Masked exit codes
case $version in 2.*) :;; 2.6.*) # Shadowed case branches
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Portability&lt;/h3&gt; 
&lt;p&gt;ShellCheck will warn when using features not supported by the shebang. For example, if you set the shebang to &lt;code&gt;#!/bin/sh&lt;/code&gt;, ShellCheck will warn about portability issues similar to &lt;code&gt;checkbashisms&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;echo {1..$n}                     # Works in ksh, but not bash/dash/sh
echo {1..10}                     # Works in ksh and bash, but not dash/sh
echo -n 42                       # Works in ksh, bash and dash, undefined in sh
expr match str regex             # Unportable alias for `expr str : regex`
trap &#39;exit 42&#39; sigint            # Unportable signal spec
cmd &amp;amp;&amp;gt; file                      # Unportable redirection operator
read foo &amp;lt; /dev/tcp/host/22      # Unportable intercepted files
foo-bar() { ..; }                # Undefined/unsupported function name
[ $UID = 0 ]                     # Variable undefined in dash/sh
local var=value                  # local is undefined in sh
time sleep 1 | sleep 5           # Undefined uses of &#39;time&#39;
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Miscellaneous&lt;/h3&gt; 
&lt;p&gt;ShellCheck recognizes a menagerie of other issues:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;PS1=&#39;\e[0;32m\$\e[0m &#39;            # PS1 colors not in \[..\]
PATH=&quot;$PATH:~/bin&quot;                # Literal tilde in $PATH
rm “file”                         # Unicode quotes
echo &quot;Hello world&quot;                # Carriage return / DOS line endings
echo hello \                      # Trailing spaces after \
var=42 echo $var                  # Expansion of inlined environment
!# bin/bash -x -e                 # Common shebang errors
echo $((n/180*100))               # Unnecessary loss of precision
ls *[:digit:].txt                 # Bad character class globs
sed &#39;s/foo/bar/&#39; file &amp;gt; file      # Redirecting to input
var2=$var2                        # Variable assigned to itself
[ x$var = xval ]                  # Antiquated x-comparisons
ls() { ls -l &quot;$@&quot;; }              # Infinitely recursive wrapper
alias ls=&#39;ls -l&#39;; ls foo          # Alias used before it takes effect
for x; do for x; do               # Nested loop uses same variable
while getopts &quot;a&quot; f; do case $f in &quot;b&quot;) # Unhandled getopts flags
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Testimonials&lt;/h2&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;At first you&#39;re like &quot;shellcheck is awesome&quot; but then you&#39;re like &quot;wtf are we still using bash&quot;&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;Alexander Tarasikov, &lt;a href=&quot;https://twitter.com/astarasikov/status/568825996532707330&quot;&gt;via Twitter&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Ignoring issues&lt;/h2&gt; 
&lt;p&gt;Issues can be ignored via environmental variable, command line, individually or globally within a file:&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/Ignore&quot;&gt;https://github.com/koalaman/shellcheck/wiki/Ignore&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Reporting bugs&lt;/h2&gt; 
&lt;p&gt;Please use the GitHub issue tracker for any bugs or feature suggestions:&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/koalaman/shellcheck/issues&quot;&gt;https://github.com/koalaman/shellcheck/issues&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Contributing&lt;/h2&gt; 
&lt;p&gt;Please submit patches to code or documentation as GitHub pull requests! Check out the &lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/DevGuide&quot;&gt;DevGuide&lt;/a&gt; on the ShellCheck Wiki.&lt;/p&gt; 
&lt;p&gt;Contributions must be licensed under the GNU GPLv3. The contributor retains the copyright.&lt;/p&gt; 
&lt;h2&gt;Copyright&lt;/h2&gt; 
&lt;p&gt;ShellCheck is licensed under the GNU General Public License, v3. A copy of this license is included in the file &lt;a href=&quot;https://raw.githubusercontent.com/koalaman/shellcheck/master/LICENSE&quot;&gt;LICENSE&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;Copyright 2012-2019, &lt;a href=&quot;https://github.com/koalaman/&quot;&gt;Vidar &#39;koala_man&#39; Holen&lt;/a&gt; and contributors.&lt;/p&gt; 
&lt;p&gt;Happy ShellChecking!&lt;/p&gt; 
&lt;h2&gt;Other Resources&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;The wiki has &lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/Checks&quot;&gt;long form descriptions&lt;/a&gt; for each warning, e.g. &lt;a href=&quot;https://github.com/koalaman/shellcheck/wiki/SC2221&quot;&gt;SC2221&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;ShellCheck does not attempt to enforce any kind of formatting or indenting style, so also check out &lt;a href=&quot;https://github.com/mvdan/sh&quot;&gt;shfmt&lt;/a&gt;!&lt;/li&gt; 
&lt;/ul&gt;</description>
      
      <media:content url="https://opengraph.githubassets.com/400047e99024d37b92da478d88076554088db17c43080c7c90b535664e661e25/koalaman/shellcheck" medium="image" />
      
    </item>
    
    <item>
      <title>PostgREST/postgrest</title>
      <link>https://github.com/PostgREST/postgrest</link>
      <description>&lt;p&gt;REST API for any Postgres database&lt;/p&gt;&lt;hr&gt;&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/PostgREST/postgrest/main/static/postgrest.png&quot; alt=&quot;Logo&quot; title=&quot;Logo&quot; /&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.patreon.com/postgrest&quot;&gt;&lt;img src=&quot;https://img.shields.io/badge/Donate-Patreon-orange.svg?colorB=F96854&quot; alt=&quot;Donate&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://postgrest.org&quot;&gt;&lt;img src=&quot;https://img.shields.io/badge/docs-latest-brightgreen.svg?style=flat&quot; alt=&quot;Docs&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://hub.docker.com/r/postgrest/postgrest/&quot;&gt;&lt;img src=&quot;https://img.shields.io/docker/pulls/postgrest/postgrest.svg?sanitize=true&quot; alt=&quot;Docker Stars&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://github.com/PostgREST/postgrest/actions?query=branch%3Amain&quot;&gt;&lt;img src=&quot;https://github.com/postgrest/postgrest/actions/workflows/ci.yaml/badge.svg?branch=main&quot; alt=&quot;Build Status&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://app.codecov.io/gh/PostgREST/postgrest&quot;&gt;&lt;img src=&quot;https://img.shields.io/codecov/c/github/postgrest/postgrest/main&quot; alt=&quot;Coverage Status&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://hackage.haskell.org/package/postgrest&quot;&gt;&lt;img src=&quot;https://img.shields.io/hackage/v/postgrest.svg?label=hackage&quot; alt=&quot;Hackage docs&quot; /&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;PostgREST serves a fully RESTful API from any existing PostgreSQL database. It provides a cleaner, more standards-compliant, faster API than you are likely to write from scratch.&lt;/p&gt; 
&lt;h2&gt;Sponsors&lt;/h2&gt; 
&lt;table align=&quot;center&quot;&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td align=&quot;center&quot; valign=&quot;middle&quot;&gt; &lt;a href=&quot;https://www.cybertec-postgresql.com/en/?utm_source=postgrest.org&amp;amp;utm_medium=referral&amp;amp;utm_campaign=postgrest&quot; target=&quot;_blank&quot;&gt; &lt;img width=&quot;296px&quot; src=&quot;https://raw.githubusercontent.com/PostgREST/postgrest/main/static/cybertec.svg?sanitize=true&quot; /&gt; &lt;/a&gt; &lt;/td&gt; 
   &lt;td align=&quot;center&quot; valign=&quot;middle&quot;&gt; &lt;a href=&quot;https://supabase.io?utm_source=postgrest%20backers&amp;amp;utm_medium=open%20source%20partner&amp;amp;utm_campaign=postgrest%20backers%20github&amp;amp;utm_term=homepage&quot; target=&quot;_blank&quot;&gt; &lt;img width=&quot;296px&quot; src=&quot;https://raw.githubusercontent.com/PostgREST/postgrest/main/static/supabase.svg?sanitize=true&quot; /&gt; &lt;/a&gt; &lt;/td&gt; 
   &lt;td align=&quot;center&quot; valign=&quot;middle&quot;&gt; &lt;a href=&quot;https://www.euronodes.com/postgrest&quot; target=&quot;_blank&quot;&gt; &lt;img width=&quot;296px&quot; src=&quot;https://raw.githubusercontent.com/PostgREST/postgrest/main/static/euronodes.svg?sanitize=true&quot; /&gt; &lt;/a&gt; &lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt;&lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td align=&quot;center&quot; valign=&quot;middle&quot;&gt; &lt;a href=&quot;https://neon.tech/?utm_source=sponsor&amp;amp;utm_campaign=postgrest&quot; target=&quot;_blank&quot;&gt; &lt;img width=&quot;296px&quot; src=&quot;https://raw.githubusercontent.com/PostgREST/postgrest/main/static/neon.jpg&quot; /&gt; &lt;/a&gt; &lt;/td&gt; 
   &lt;td align=&quot;center&quot; valign=&quot;middle&quot;&gt; &lt;a href=&quot;https://www.bytebase.com/?utm_source=sponsor&amp;amp;utm_campaign=postgrest&quot; target=&quot;_blank&quot;&gt; &lt;img width=&quot;296px&quot; src=&quot;https://raw.githubusercontent.com/PostgREST/postgrest/main/static/bytebase.svg?sanitize=true&quot; /&gt; &lt;/a&gt; &lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;Big thanks to our sponsors! You can join them by supporting PostgREST on &lt;a href=&quot;https://www.patreon.com/postgrest&quot;&gt;Patreon&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;Usage&lt;/h2&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;See the docs for &lt;a href=&quot;https://docs.postgrest.org/en/stable/explanations/install.html&quot;&gt;how to install PostgREST on your platform&lt;/a&gt;. You can also &lt;a href=&quot;https://docs.postgrest.org/en/stable/explanations/install.html#docker&quot;&gt;use Docker&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Invoke for help:&lt;/p&gt; &lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;postgrest --help
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;h2&gt;&lt;a href=&quot;http://postgrest.org&quot;&gt;Documentation&lt;/a&gt;&lt;/h2&gt; 
&lt;p&gt;Latest documentation is at &lt;a href=&quot;http://postgrest.org&quot;&gt;postgrest.org&lt;/a&gt;. You can contribute to the docs in &lt;a href=&quot;https://github.com/PostgREST/postgrest/tree/main/docs&quot;&gt;PostgREST/postgrest/docs&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;Performance&lt;/h2&gt; 
&lt;p&gt;TLDR; subsecond response times for up to 2000 requests/sec on Heroku free tier. If you&#39;re used to servers written in interpreted languages, prepare to be pleasantly surprised by PostgREST performance.&lt;/p&gt; 
&lt;p&gt;Three factors contribute to the speed. First the server is written in &lt;a href=&quot;https://www.haskell.org/&quot;&gt;Haskell&lt;/a&gt; using the &lt;a href=&quot;http://www.yesodweb.com/blog/2011/03/preliminary-warp-cross-language-benchmarks&quot;&gt;Warp&lt;/a&gt; HTTP server (aka a compiled language with lightweight threads). Next it delegates as much calculation as possible to the database including&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Serializing JSON responses directly in SQL&lt;/li&gt; 
 &lt;li&gt;Data validation&lt;/li&gt; 
 &lt;li&gt;Authorization&lt;/li&gt; 
 &lt;li&gt;Combined row counting and retrieval&lt;/li&gt; 
 &lt;li&gt;Data post in single command (&lt;code&gt;returning *&lt;/code&gt;)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Finally it uses the database efficiently with the &lt;a href=&quot;https://nikita-volkov.github.io/hasql-benchmarks/&quot;&gt;Hasql&lt;/a&gt; library by&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Keeping a pool of db connections&lt;/li&gt; 
 &lt;li&gt;Using the PostgreSQL binary protocol&lt;/li&gt; 
 &lt;li&gt;Being stateless to allow horizontal scaling&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Security&lt;/h2&gt; 
&lt;p&gt;PostgREST &lt;a href=&quot;http://postgrest.org/en/stable/auth.html&quot;&gt;handles authentication&lt;/a&gt; (via JSON Web Tokens) and delegates authorization to the role information defined in the database. This ensures there is a single declarative source of truth for security. When dealing with the database the server assumes the identity of the currently authenticated user, and for the duration of the connection cannot do anything the user themselves couldn&#39;t. Other forms of authentication can be built on top of the JWT primitive. See the docs for more information.&lt;/p&gt; 
&lt;h2&gt;Versioning&lt;/h2&gt; 
&lt;p&gt;A robust long-lived API needs the freedom to exist in multiple versions. PostgREST does versioning through database schemas. This allows you to expose tables and views without making the app brittle. Underlying tables can be superseded and hidden behind public facing views.&lt;/p&gt; 
&lt;h2&gt;Self-documentation&lt;/h2&gt; 
&lt;p&gt;PostgREST uses the &lt;a href=&quot;https://openapis.org/&quot;&gt;OpenAPI&lt;/a&gt; standard to generate up-to-date documentation for APIs. You can use a tool like &lt;a href=&quot;https://github.com/swagger-api/swagger-ui&quot;&gt;Swagger-UI&lt;/a&gt; to render interactive documentation for demo requests against the live API server.&lt;/p&gt; 
&lt;p&gt;This project uses HTTP to communicate other metadata as well. For instance the number of rows returned by an endpoint is reported by - and limited with - range headers. More about &lt;a href=&quot;http://begriffs.com/posts/2014-03-06-beyond-http-header-links.html&quot;&gt;that&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;Data Integrity&lt;/h2&gt; 
&lt;p&gt;Rather than relying on an Object Relational Mapper and custom imperative coding, this system requires you to put declarative constraints directly into your database. Hence no application can corrupt your data (including your API server).&lt;/p&gt; 
&lt;p&gt;The PostgREST exposes HTTP interface with safeguards to prevent surprises, such as enforcing idempotent PUT requests.&lt;/p&gt; 
&lt;p&gt;See examples of &lt;a href=&quot;http://www.tutorialspoint.com/postgresql/postgresql_constraints.htm&quot;&gt;PostgreSQL constraints&lt;/a&gt; and the &lt;a href=&quot;http://postgrest.org/en/stable/api.html&quot;&gt;API guide&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;Supporting development&lt;/h2&gt; 
&lt;p&gt;You can help PostgREST ongoing maintenance and development by making a regular donation through Patreon &lt;a href=&quot;https://www.patreon.com/postgrest&quot;&gt;https://www.patreon.com/postgrest&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Every donation will be spent on making PostgREST better for the whole community.&lt;/p&gt; 
&lt;h2&gt;Contributing&lt;/h2&gt; 
&lt;p&gt;Contributions are always welcome and appreciated. Please see the &lt;a href=&quot;https://github.com/PostgREST/postgrest/raw/main/CONTRIBUTING.md&quot;&gt;Contributing guidelines&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;Thanks&lt;/h2&gt; 
&lt;p&gt;The PostgREST organization is grateful to:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;The project &lt;a href=&quot;https://github.com/PostgREST/postgrest/raw/main/BACKERS.md&quot;&gt;sponsors and backers&lt;/a&gt; who support PostgREST&#39;s development.&lt;/li&gt; 
 &lt;li&gt;The project &lt;a href=&quot;https://github.com/PostgREST/postgrest/graphs/contributors&quot;&gt;contributors&lt;/a&gt; who have improved PostgREST immensely with their code and good judgement. See more details in the &lt;a href=&quot;https://github.com/PostgREST/postgrest/raw/main/CHANGELOG.md&quot;&gt;changelog&lt;/a&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;The cool logo came from &lt;a href=&quot;https://github.com/casalaina&quot;&gt;Mikey Casalaina&lt;/a&gt;.&lt;/p&gt;</description>
      
      <media:content url="https://opengraph.githubassets.com/66af15231b81bda97dd3b589b6c38fe687ec7baaa2f6d17c0ec5a94ce82c916a/PostgREST/postgrest" medium="image" />
      
    </item>
    
    <item>
      <title>mtolly/onyx</title>
      <link>https://github.com/mtolly/onyx</link>
      <description>&lt;p&gt;Toolkit for converting and building songs for Rock Band, Guitar Hero, Clone Hero, and other similar rhythm games&lt;/p&gt;&lt;hr&gt;&lt;h1&gt;Onyx Music Game Toolkit&lt;/h1&gt; 
&lt;p&gt;I transcribe songs for use in Harmonix&#39;s &lt;em&gt;Rock Band 3&lt;/em&gt; and other similar rhythm games. Along the way, I&#39;ve written a helpful program to streamline the build process, and do all sorts of useful conversions and transformations.&lt;/p&gt; 
&lt;p&gt;Download from the &lt;a href=&quot;https://github.com/mtolly/onyx/releases&quot;&gt;releases page&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/mtolly/onyx/master/haskell/screenshot.png&quot; alt=&quot;Screenshot of Onyx&#39;s song preview tool&quot; /&gt;&lt;/p&gt; 
&lt;h1&gt;Onyxite&#39;s Custom Songs&lt;/h1&gt; 
&lt;p&gt;This repository contains the &quot;source&quot; for charts which (once finished) are available from &lt;a href=&quot;http://customscreators.com/index.php?/topic/14398-onyxites-customs/&quot;&gt;my thread on the Customs Creators forum&lt;/a&gt;, or from &lt;a href=&quot;https://onyxite.org/customs/&quot;&gt;my own website&lt;/a&gt; (work in progress).&lt;/p&gt; 
&lt;h2&gt;Licensing&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;http://creativecommons.org/licenses/by-sa/4.0/&quot;&gt;&lt;img src=&quot;https://i.creativecommons.org/l/by-sa/4.0/88x31.png&quot; alt=&quot;Creative Commons License&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://www.gnu.org/licenses/gpl.html&quot;&gt;&lt;img src=&quot;https://www.gnu.org/graphics/gplv3-88x31.png&quot; alt=&quot;GNU GPL License&quot; /&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;The Onyx software is free software via the &lt;a href=&quot;https://www.gnu.org/licenses/gpl.html&quot;&gt;GNU GPL v3&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;My transcriptions (&lt;em&gt;not&lt;/em&gt; the compositions) are freely licensed under &lt;a href=&quot;http://creativecommons.org/licenses/by-sa/4.0/&quot;&gt;Creative Commons Attribution-ShareAlike&lt;/a&gt;. All compositions are the property of the original artists.&lt;/p&gt; 
&lt;p&gt;In addition to my own charts, this repository contains work by several other authors, including: Harmonix, &lt;a href=&quot;https://www.youtube.com/user/SHGrinnz&quot;&gt;Grinnz&lt;/a&gt;, &lt;a href=&quot;http://pksage.com/ccc/IPS/index.php?/topic/13775-mazegeeks-customs-1117-tarkus-by-emerson-lake-palmer/&quot;&gt;mazegeek999&lt;/a&gt;, &lt;a href=&quot;http://www.fretsonfire.net/forums/viewtopic.php?f=5&amp;amp;t=45301&quot;&gt;TheLieInKing&lt;/a&gt;, and more. (Credited in individual song READMEs.) Other authors&#39; work hosted here is &lt;em&gt;not&lt;/em&gt; necessarily licensed in the same way; please contact them if you want permission to redistribute or repackage charts.&lt;/p&gt;</description>
      
      <media:content url="https://opengraph.githubassets.com/b482589e533fd8fd43a9a03e470b5daca87a7423be25ce9bb8602571253c7276/mtolly/onyx" medium="image" />
      
    </item>
    
    <item>
      <title>unisonweb/unison</title>
      <link>https://github.com/unisonweb/unison</link>
      <description>&lt;p&gt;A friendly programming language from the future&lt;/p&gt;&lt;hr&gt;&lt;h1&gt;The Unison language&lt;/h1&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/unisonweb/unison/actions/workflows/ci.yaml?query=branch%3Atrunk&quot;&gt;&lt;img src=&quot;https://github.com/unisonweb/unison/actions/workflows/ci.yaml/badge.svg?sanitize=true&quot; alt=&quot;CI Status&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://github.com/unisonweb/unison/actions/workflows/pre-release.yaml&quot;&gt;&lt;img src=&quot;https://github.com/unisonweb/unison/actions/workflows/pre-release.yaml/badge.svg?sanitize=true&quot; alt=&quot;Pre-Release Status&quot; /&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/unisonweb/unison/trunk/#overview&quot;&gt;Overview&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/unisonweb/unison/trunk/#building-using-stack&quot;&gt;Building using Stack&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/unisonweb/unison/trunk/docs/language-server.markdown&quot;&gt;Language Server Protocol (LSP)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/unisonweb/unison/trunk/#codebase-server&quot;&gt;Codebase Server&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/unisonweb/unison/trunk/docs/configuration.md&quot;&gt;Configuration&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;img src=&quot;https://repobeats.axiom.co/api/embed/92b662a65fd842d49cb8d7d813043f5f5b4b550d.svg?sanitize=true&quot; alt=&quot;Alt&quot; title=&quot;Repobeats analytics image&quot; /&gt;&lt;/p&gt; 
&lt;h2&gt;Overview&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://unison-lang.org&quot;&gt;Unison&lt;/a&gt; is a statically-typed functional language with type inference, an effect system, and advanced tooling. It is based around &lt;a href=&quot;https://www.unison-lang.org/learn/the-big-idea/&quot;&gt;a big idea of content-addressed code&lt;/a&gt;, in which function are identified by a hash of their implementation rather than by name, and code is stored as its AST in a database. This provides a number of benefits:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;No builds. Unison has perfect incremental compilation, with a shared compilation cache that is part of the codebase format. Despite the strong static typing, you are almost never waiting for code to compile.&lt;/li&gt; 
 &lt;li&gt;Instant, non-breaking renaming of definitions.&lt;/li&gt; 
 &lt;li&gt;Perfect caching of tests, only rerunning determinstic tests if dependencies changed.&lt;/li&gt; 
 &lt;li&gt;Semantically-aware version control, avoiding spurious merge conflicts from things like order of imports, whitespace or code formatting differences, and so on.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Unison can be used like any other general-purpose language, or you can use it in conjunction with &lt;a href=&quot;https://unison.cloud&quot;&gt;Unison Cloud&lt;/a&gt; for building distributed systems.&lt;/p&gt; 
&lt;p&gt;Here is some sample code:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-Haskell&quot;&gt;-- A comment!
-- Function signatures appear before the definition
factorial : Nat -&amp;gt; Nat
factorial n = product (range 1 (n + 1))

-- Signatures can be left off; they will be inferred
List.map f as =
  go acc rem = match rem with
    [] -&amp;gt; acc
    a +: as -&amp;gt; go (acc :+ f a) as
  go [] as

&amp;gt; List.map (x -&amp;gt; x * 10) (range 0 10)
= [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]

&amp;gt; List.map factorial [1,2,3,4]
= [1, 2, 6, 24]
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Functions arguments are separated by spaces instead of parens and commas. Loops are written using recursion (above the helper function &lt;code&gt;go&lt;/code&gt; defines a loop). The language supports pattern matching via &lt;code&gt;match &amp;lt;expr&amp;gt; with &amp;lt;cases&amp;gt;&lt;/code&gt;, which works for lists and also user-defined data types.&lt;/p&gt; 
&lt;p&gt;Other resources:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.unison-lang.org/learn/the-big-idea/&quot;&gt;Learn about the big idea behind Unison&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Check out &lt;a href=&quot;https://unison-lang.org&quot;&gt;the project website&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Say hello or lurk &lt;a href=&quot;https://unison-lang.org/discord&quot;&gt;in the Discord chat&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Explore &lt;a href=&quot;https://share.unison-lang.org/&quot;&gt;the Unison ecosystem&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.unison-lang.org/learn/&quot;&gt;Learn Unison&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Building using Stack&lt;/h2&gt; 
&lt;p&gt;If these instructions don&#39;t work for you or are incomplete, please file an issue.&lt;/p&gt; 
&lt;p&gt;The build uses &lt;a href=&quot;http://docs.haskellstack.org/&quot;&gt;Stack&lt;/a&gt;. If you don&#39;t already have it installed, &lt;a href=&quot;http://docs.haskellstack.org/en/stable/README.html#how-to-install&quot;&gt;follow the install instructions&lt;/a&gt; for your platform. (Hint: &lt;code&gt;brew update &amp;amp;&amp;amp; brew install stack&lt;/code&gt;)&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;$ git clone https://github.com/unisonweb/unison.git
$ cd unison
$ stack --version # we&#39;ll want to know this version if you run into trouble
$ stack build --fast --test &amp;amp;&amp;amp; stack exec unison
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;To run the Unison Local UI while building from source, you can use the &lt;code&gt;/dev-ui-install.sh&lt;/code&gt; script. It will download the latest release of &lt;a href=&quot;https://github.com/unisonweb/unison-local-ui&quot;&gt;unison-local-ui&lt;/a&gt; and put it in the expected location for the unison executable created by &lt;code&gt;stack build&lt;/code&gt;. When you start unison, you&#39;ll see a url where Unison Local UI is running.&lt;/p&gt; 
&lt;p&gt;See &lt;a href=&quot;https://raw.githubusercontent.com/unisonweb/unison/trunk/development.markdown&quot;&gt;&lt;code&gt;development.markdown&lt;/code&gt;&lt;/a&gt; for a list of build commands you&#39;ll likely use during development.&lt;/p&gt; 
&lt;h2&gt;Language Server Protocol (LSP)&lt;/h2&gt; 
&lt;p&gt;View Language Server setup instructions &lt;a href=&quot;https://raw.githubusercontent.com/unisonweb/unison/trunk/docs/language-server.markdown&quot;&gt;here&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;AI Agent Server (MCP)&lt;/h2&gt; 
&lt;p&gt;View AI Agent Server setup instructions &lt;a href=&quot;https://raw.githubusercontent.com/unisonweb/unison/trunk/docs/mcp.md&quot;&gt;here&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;Codebase Server&lt;/h2&gt; 
&lt;p&gt;When &lt;code&gt;ucm&lt;/code&gt; starts it starts a Codebase web server that is used by the &lt;a href=&quot;https://github.com/unisonweb/unison-local-ui&quot;&gt;Unison Local UI&lt;/a&gt;. It selects a random port and a unique token that must be used when starting the UI to correctly connect to the server.&lt;/p&gt; 
&lt;p&gt;The port, host and token can all be configured by providing environment variables when starting &lt;code&gt;ucm&lt;/code&gt;: &lt;code&gt;UCM_PORT&lt;/code&gt;, &lt;code&gt;UCM_HOST&lt;/code&gt;, and &lt;code&gt;UCM_TOKEN&lt;/code&gt;.&lt;/p&gt; 
&lt;h2&gt;Configuration&lt;/h2&gt; 
&lt;p&gt;See the documentation for configuration &lt;a href=&quot;https://raw.githubusercontent.com/unisonweb/unison/trunk/docs/configuration.md&quot;&gt;here&lt;/a&gt;&lt;/p&gt;</description>
      
      <media:content url="https://opengraph.githubassets.com/2af8e69d26195504aa81fc5d8d0c9524641365f3559ea25859e5ac2c21237bf9/unisonweb/unison" medium="image" />
      
    </item>
    
    <item>
      <title>simplex-chat/simplexmq</title>
      <link>https://github.com/simplex-chat/simplexmq</link>
      <description>&lt;p&gt;⚙️ SimpleXMQ - A reference implementation of the SimpleX Messaging Protocol for simplex queues over public networks.&lt;/p&gt;&lt;hr&gt;&lt;h1&gt;SimpleXMQ&lt;/h1&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/simplex-chat/simplexmq/actions/workflows/build.yml&quot;&gt;&lt;img src=&quot;https://github.com/simplex-chat/simplexmq/actions/workflows/build.yml/badge.svg?sanitize=true&quot; alt=&quot;GitHub build&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://github.com/simplex-chat/simplexmq/releases&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/v/release/simplex-chat/simplexmq&quot; alt=&quot;GitHub release&quot; /&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;📢 SimpleXMQ v1 is released - with many security, privacy and efficiency improvements, new functionality - see &lt;a href=&quot;https://github.com/simplex-chat/simplexmq/releases/tag/v1.0.0&quot;&gt;release notes&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Please note&lt;/strong&gt;: v1 is not backwards compatible, but it has the version negotiation built into all protocol layers for forwards compatibility of this version and backwards compatibility of the future versions, that will be backwards compatible for at least two versions back.&lt;/p&gt; 
&lt;p&gt;If you have a server deployed please deploy a new server to a new host and retire the previous version once it is no longer used.&lt;/p&gt; 
&lt;h2&gt;Message broker for unidirectional (simplex) queues&lt;/h2&gt; 
&lt;p&gt;SimpleXMQ is a message broker for managing message queues and sending messages over public network. It consists of SMP server, SMP client library and SMP agent that implement &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplexmq/stable/protocol/simplex-messaging.md&quot;&gt;SMP protocol&lt;/a&gt; for client-server communication and &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplexmq/stable/protocol/agent-protocol.md&quot;&gt;SMP agent protocol&lt;/a&gt; to manage duplex connections via simplex queues on multiple SMP servers.&lt;/p&gt; 
&lt;p&gt;SMP protocol is inspired by &lt;a href=&quot;https://redis.io/topics/protocol&quot;&gt;Redis serialization protocol&lt;/a&gt;, but it is much simpler - it currently has only 10 client commands and 8 server responses.&lt;/p&gt; 
&lt;p&gt;SimpleXMQ is implemented in Haskell - it benefits from robust software transactional memory (STM) and concurrency primitives that Haskell provides.&lt;/p&gt; 
&lt;h2&gt;SimpleXMQ roadmap&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;SimpleX service protocol and application template - to enable users building services and chat bots that work over SimpleX protocol stack. The first such service will be a notification service for a mobile app.&lt;/li&gt; 
 &lt;li&gt;SMP queue redundancy and rotation in SMP agent connections.&lt;/li&gt; 
 &lt;li&gt;SMP agents synchronization to share connections and messages between multiple agents (it would allow using multiple devices for &lt;a href=&quot;https://github.com/simplex-chat/simplex-chat&quot;&gt;simplex-chat&lt;/a&gt;).&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Components&lt;/h2&gt; 
&lt;h3&gt;SMP server&lt;/h3&gt; 
&lt;p&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplexmq/stable/apps/smp-server/Main.hs&quot;&gt;SMP server&lt;/a&gt; can be run on any Linux distribution, including low power/low memory devices. OpenSSL library is required for initialization.&lt;/p&gt; 
&lt;p&gt;To initialize the server use &lt;code&gt;smp-server init -n &amp;lt;fqdn&amp;gt;&lt;/code&gt; (or &lt;code&gt;smp-server init --ip &amp;lt;ip&amp;gt;&lt;/code&gt; for IP based address) command - it will generate keys and certificates for TLS transport. The fingerprint of offline certificate is used as part of the server address to protect client/server connection against man-in-the-middle attacks: &lt;code&gt;smp://&amp;lt;fingerprint&amp;gt;@&amp;lt;hostname&amp;gt;[:5223]&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;SMP server uses in-memory persistence with an optional append-only log of created queues that allows to re-start the server without losing the connections. This log is compacted on every server restart, permanently removing suspended and removed queues.&lt;/p&gt; 
&lt;p&gt;To enable store log, initialize server using &lt;code&gt;smp-server -l&lt;/code&gt; command, or modify &lt;code&gt;smp-server.ini&lt;/code&gt; created during initialization (uncomment &lt;code&gt;enable = on&lt;/code&gt; option in the store log section). Use &lt;code&gt;smp-server --help&lt;/code&gt; for other usage tips.&lt;/p&gt; 
&lt;p&gt;Starting from version 2.3.0, when store log is enabled, the server would also enable saving undelivered messages on exit and restoring them on start. This can be disabled via a separate setting &lt;code&gt;restore_messages&lt;/code&gt; in &lt;code&gt;smp-server.ini&lt;/code&gt; file. Saving messages would only work if the server is stopped with SIGINT signal (keyboard interrupt), if it is stopped with SIGTERM signal the messages would not be saved.&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&lt;strong&gt;Please note:&lt;/strong&gt; On initialization SMP server creates a chain of two certificates: a self-signed CA certificate (&quot;offline&quot;) and a server certificate used for TLS handshake (&quot;online&quot;). &lt;strong&gt;You should store CA certificate private key securely and delete it from the server. If server TLS credential is compromised this key can be used to sign a new one, keeping the same server identity and established connections.&lt;/strong&gt; CA private key location by default is &lt;code&gt;/etc/opt/simplex/ca.key&lt;/code&gt;.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;SMP server implements &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplexmq/stable/protocol/simplex-messaging.md&quot;&gt;SMP protocol&lt;/a&gt;.&lt;/p&gt; 
&lt;h4&gt;Running SMP server on MacOS&lt;/h4&gt; 
&lt;p&gt;SMP server requires OpenSSL library for initialization. On MacOS OpenSSL library may be replaced with LibreSSL, which doesn&#39;t support required algorithms. Before initializing SMP server verify you have OpenSSL installed:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;openssl version
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;If it says &quot;LibreSSL&quot;, please install original OpenSSL:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;brew update
brew install openssl
echo &#39;PATH=&quot;/opt/homebrew/opt/openssl@3/bin:$PATH&quot;&#39; &amp;gt;&amp;gt; ~/.zprofile # or follow whatever instructions brew suggests
. ~/.zprofile # or restart your terminal to start a new session
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Now &lt;code&gt;openssl version&lt;/code&gt; should be saying &quot;OpenSSL&quot;. You can now run &lt;code&gt;smp-server init&lt;/code&gt; to initialize your SMP server.&lt;/p&gt; 
&lt;h3&gt;SMP client library&lt;/h3&gt; 
&lt;p&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplexmq/stable/src/Simplex/Messaging/Client.hs&quot;&gt;SMP client&lt;/a&gt; is a Haskell library to connect to SMP servers that allows to:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;execute commands with a functional API.&lt;/li&gt; 
 &lt;li&gt;receive messages and other notifications via STM queue.&lt;/li&gt; 
 &lt;li&gt;automatically send keep-alive commands.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;SMP agent&lt;/h3&gt; 
&lt;p&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplexmq/stable/src/Simplex/Messaging/Agent.hs&quot;&gt;SMP agent library&lt;/a&gt; can be used to run SMP agent as part of another application and to communicate with the agent via STM queues, without serializing and parsing commands and responses.&lt;/p&gt; 
&lt;p&gt;Haskell type &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplexmq/stable/src/Simplex/Messaging/Agent/Protocol.hs&quot;&gt;ACommand&lt;/a&gt; represents SMP agent protocol to communicate via STM queues.&lt;/p&gt; 
&lt;p&gt;See &lt;a href=&quot;https://github.com/simplex-chat/simplex-chat&quot;&gt;simplex-chat&lt;/a&gt; terminal UI for the example of integrating SMP agent into another application.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplexmq/stable/apps/smp-agent/Main.hs&quot;&gt;SMP agent executable&lt;/a&gt; can be used to run a standalone SMP agent process that implements plaintext &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplexmq/stable/protocol/agent-protocol.md&quot;&gt;SMP agent protocol&lt;/a&gt; via TCP port 5224, so it can be used via telnet. It can be deployed in private networks to share access to the connections between multiple applications and services.&lt;/p&gt; 
&lt;h2&gt;Using SMP server and SMP agent&lt;/h2&gt; 
&lt;p&gt;You can either run your own SMP server locally or deploy using &lt;a href=&quot;https://cloud.linode.com/stackscripts/748014&quot;&gt;Linode StackScript&lt;/a&gt;, or try local SMP agent with the deployed servers:&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;smp://u2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU=@smp4.simplex.im&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;smp://hpq7_4gGJiilmz5Rf-CswuU5kZGkm_zOIooSw6yALRg=@smp5.simplex.im&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;smp://PQUV2eL0t7OStZOoAsPEV2QYWt4-xilbakvGUGOItUo=@smp6.simplex.im&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;It&#39;s the easiest to try SMP agent via a prototype &lt;a href=&quot;https://github.com/simplex-chat/simplex-chat&quot;&gt;simplex-chat&lt;/a&gt; terminal UI.&lt;/p&gt; 
&lt;h2&gt;Deploy SMP/XFTP servers on Linux&lt;/h2&gt; 
&lt;p&gt;You can run your SMP/XFTP server as a Linux process, optionally using a service manager for booting and restarts.&lt;/p&gt; 
&lt;p&gt;Notice that &lt;code&gt;smp-server&lt;/code&gt; and &lt;code&gt;xftp-server&lt;/code&gt; requires &lt;code&gt;openssl&lt;/code&gt; as run-time dependency (it is used to generate server certificates during initialization). Install it with your packet manager:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;# For Ubuntu
apt update &amp;amp;&amp;amp; apt install openssl
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Install binaries&lt;/h3&gt; 
&lt;h4&gt;Using Docker&lt;/h4&gt; 
&lt;p&gt;On Linux, you can deploy smp and xftp server using Docker. This will download image from &lt;a href=&quot;https://hub.docker.com/r/simplexchat&quot;&gt;Docker Hub&lt;/a&gt;.&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;Create directories for persistent Docker configuration:&lt;/p&gt; &lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;mkdir -p $HOME/simplex/{xftp,smp}/{config,logs} &amp;amp;&amp;amp; mkdir -p $HOME/simplex/xftp/files
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Run your Docker container.&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt; &lt;p&gt;&lt;code&gt;smp-server&lt;/code&gt;&lt;/p&gt; &lt;p&gt;You must change &lt;strong&gt;your_ip_or_domain&lt;/strong&gt;. &lt;code&gt;-e &quot;pass=password&quot;&lt;/code&gt; is optional variable to password-protect your &lt;code&gt;smp&lt;/code&gt; server:&lt;/p&gt; &lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;docker run -d \
    -e &quot;ADDR=your_ip_or_domain&quot; \
    -e &quot;PASS=password&quot; \
    -p 5223:5223 \
    -v $HOME/simplex/smp/config:/etc/opt/simplex:z \
    -v $HOME/simplex/smp/logs:/var/opt/simplex:z \
    simplexchat/smp-server:latest
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;code&gt;xftp-server&lt;/code&gt;&lt;/p&gt; &lt;p&gt;You must change &lt;strong&gt;your_ip_or_domain&lt;/strong&gt; and &lt;strong&gt;maximum_storage&lt;/strong&gt;.&lt;/p&gt; &lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;docker run -d \
    -e &quot;ADDR=your_ip_or_domain&quot; \
    -e &quot;QUOTA=maximum_storage&quot; \
    -p 443:443 \
    -v $HOME/simplex/xftp/config:/etc/opt/simplex-xftp:z \
    -v $HOME/simplex/xftp/logs:/var/opt/simplex-xftp:z \
    -v $HOME/simplex/xftp/files:/srv/xftp:z \
    simplexchat/xftp-server:latest
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;h4&gt;Using installation script&lt;/h4&gt; 
&lt;p&gt;&lt;strong&gt;Please note&lt;/strong&gt; that currently, only Ubuntu distribution is supported.&lt;/p&gt; 
&lt;p&gt;You can install and setup servers automatically using our script:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;curl --proto &#39;=https&#39; --tlsv1.2 -sSf https://raw.githubusercontent.com/simplex-chat/simplexmq/stable/install.sh -o simplex-server-install.sh &amp;amp;&amp;amp;\
if echo &#39;53fcdb4ceab324316e2c4cda7e84dbbb344f32550a65975a7895425e5a1be757 simplex-server-install.sh&#39; | sha256sum -c; then
  chmod +x ./simplex-server-install.sh
  ./simplex-server-install.sh
  rm ./simplex-server-install.sh
else
  echo &quot;SHA-256 checksum is incorrect!&quot;
  rm ./simplex-server-install.sh
fi
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Build from source&lt;/h3&gt; 
&lt;h4&gt;Using Docker&lt;/h4&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&lt;strong&gt;Please note:&lt;/strong&gt; to build the app use source code from &lt;a href=&quot;https://github.com/simplex-chat/simplexmq/tree/stable&quot;&gt;stable branch&lt;/a&gt;.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;On Linux, you can build smp server using Docker.&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;Build your images:&lt;/p&gt; &lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;git clone https://github.com/simplex-chat/simplexmq
cd simplexmq
git checkout stable
DOCKER_BUILDKIT=1 docker build -t local/smp-server --build-arg APP=&quot;smp-server&quot; --build-arg APP_PORT=&quot;5223&quot; . # For xmp-server
DOCKER_BUILDKIT=1 docker build -t local/xftp-server --build-arg APP=&quot;xftp-server&quot; --build-arg APP_PORT=&quot;443&quot; . # For xftp-server
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Create directories for persistent Docker configuration:&lt;/p&gt; &lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;mkdir -p $HOME/simplex/{xftp,smp}/{config,logs} &amp;amp;&amp;amp; mkdir -p $HOME/simplex/xftp/files
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Run your Docker container.&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt; &lt;p&gt;&lt;code&gt;smp-server&lt;/code&gt;&lt;/p&gt; &lt;p&gt;You must change &lt;strong&gt;your_ip_or_domain&lt;/strong&gt;. &lt;code&gt;-e &quot;pass=password&quot;&lt;/code&gt; is optional variable to password-protect your &lt;code&gt;smp&lt;/code&gt; server:&lt;/p&gt; &lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;docker run -d \
    -e &quot;ADDR=your_ip_or_domain&quot; \
    -e &quot;PASS=password&quot; \
    -p 5223:5223 \
    -v $HOME/simplex/smp/config:/etc/opt/simplex:z \
    -v $HOME/simplex/smp/logs:/var/opt/simplex:z \
    simplexchat/smp-server:latest
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;code&gt;xftp-server&lt;/code&gt;&lt;/p&gt; &lt;p&gt;You must change &lt;strong&gt;your_ip_or_domain&lt;/strong&gt; and &lt;strong&gt;maximum_storage&lt;/strong&gt;.&lt;/p&gt; &lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;docker run -d \
    -e &quot;ADDR=your_ip_or_domain&quot; \
    -e &quot;QUOTA=maximum_storage&quot; \
    -p 443:443 \
    -v $HOME/simplex/xftp/config:/etc/opt/simplex-xftp:z \
    -v $HOME/simplex/xftp/logs:/var/opt/simplex-xftp:z \
    -v $HOME/simplex/xftp/files:/srv/xftp:z \
    simplexchat/xftp-server:latest
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;h4&gt;Using your distribution&lt;/h4&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;Install dependencies and build tools (&lt;code&gt;GHC&lt;/code&gt;, &lt;code&gt;cabal&lt;/code&gt; and dev libs):&lt;/p&gt; &lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;# On Ubuntu. Depending on your distribution, use your package manager to determine package names.
sudo apt-get update &amp;amp;&amp;amp; apt-get install -y build-essential curl libffi-dev libffi7 libgmp3-dev libgmp10 libncurses-dev libncurses5 libtinfo5 pkg-config zlib1g-dev libnuma-dev libssl-dev
export BOOTSTRAP_HASKELL_GHC_VERSION=9.6.3
export BOOTSTRAP_HASKELL_CABAL_VERSION=3.10.3.0
curl --proto &#39;=https&#39; --tlsv1.2 -sSf https://get-ghcup.haskell.org | BOOTSTRAP_HASKELL_NONINTERACTIVE=1 sh
ghcup set ghc &quot;${BOOTSTRAP_HASKELL_GHC_VERSION}&quot;
ghcup set cabal &quot;${BOOTSTRAP_HASKELL_CABAL_VERSION}&quot;
source ~/.ghcup/env
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Build the project:&lt;/p&gt; &lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;git clone https://github.com/simplex-chat/simplexmq
cd simplexmq
git checkout stable
cabal update
cabal build exe:smp-server exe:xftp-server
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;List compiled binaries:&lt;/p&gt; &lt;p&gt;&lt;code&gt;smp-server&lt;/code&gt;&lt;/p&gt; &lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;cabal list-bin exe:smp-server
&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;&lt;code&gt;xftp-server&lt;/code&gt;&lt;/p&gt; &lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;cabal list-bin exe:xftp-server
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;Initialize SMP server with &lt;code&gt;smp-server init [-l] -n &amp;lt;fqdn&amp;gt;&lt;/code&gt; or &lt;code&gt;smp-server init [-l] --ip &amp;lt;ip&amp;gt;&lt;/code&gt; - depending on how you initialize it, either FQDN or IP will be used for server&#39;s address.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Run &lt;code&gt;smp-server start&lt;/code&gt; to start SMP server, or you can configure a service manager to run it as a service.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Optionally, &lt;code&gt;smp-server&lt;/code&gt; can be setup for having an onion address in &lt;code&gt;tor&lt;/code&gt; network. See: &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplexmq/stable/scripts/tor/&quot;&gt;&lt;code&gt;scripts/tor&lt;/code&gt;&lt;/a&gt;. In this case, the server address can have both public and onion hostname pointing to the same server, to allow two people connect when only one of them is using Tor. The server address would be: &lt;code&gt;smp://&amp;lt;fingerprint&amp;gt;@&amp;lt;public_hostname&amp;gt;,&amp;lt;onion_hostname&amp;gt;&lt;/code&gt;&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;See &lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplexmq/stable/#smp-server&quot;&gt;this section&lt;/a&gt; for more information. Run &lt;code&gt;smp-server -h&lt;/code&gt; and &lt;code&gt;smp-server init -h&lt;/code&gt; for explanation of commands and options.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://cloud.linode.com/stackscripts/748014&quot;&gt;&lt;img alt=&quot;Linode&quot; src=&quot;https://raw.githubusercontent.com/simplex-chat/simplexmq/stable/img/linode.svg?sanitize=true&quot; align=&quot;right&quot; width=&quot;200&quot; /&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Deploy SMP server on Linode&lt;/h2&gt; 
&lt;p&gt;* You can use free credit Linode offers when &lt;a href=&quot;https://www.linode.com/&quot;&gt;creating a new account&lt;/a&gt; to deploy an SMP server.&lt;/p&gt; 
&lt;p&gt;Deployment on Linode is performed via StackScripts, which serve as recipes for Linode instances, also called Linodes. To deploy SMP server on Linode:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Create a Linode account or login with an already existing one.&lt;/li&gt; 
 &lt;li&gt;Open &lt;a href=&quot;https://cloud.linode.com/stackscripts/748014&quot;&gt;SMP server StackScript&lt;/a&gt; and click &quot;Deploy New Linode&quot;.&lt;/li&gt; 
 &lt;li&gt;You can optionally configure the following parameters: 
  &lt;ul&gt; 
   &lt;li&gt;SMP Server store log flag for queue persistence on server restart, recommended.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.linode.com/docs/guides/getting-started-with-the-linode-api#get-an-access-token&quot;&gt;Linode API token&lt;/a&gt; to attach server address etc. as tags to Linode and to add A record to your 2nd level domain (e.g. &lt;code&gt;example.com&lt;/code&gt; &lt;a href=&quot;https://cloud.linode.com/domains/create&quot;&gt;domain should be created&lt;/a&gt; in your account prior to deployment). The API token access scopes: 
    &lt;ul&gt; 
     &lt;li&gt;read/write for &quot;linodes&quot;&lt;/li&gt; 
     &lt;li&gt;read/write for &quot;domains&quot;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Domain name to use instead of Linode IP address, e.g. &lt;code&gt;smp1.example.com&lt;/code&gt;.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Choose the region and plan, Shared CPU Nanode with 1Gb is sufficient.&lt;/li&gt; 
 &lt;li&gt;Provide ssh key to be able to connect to your Linode via ssh. If you haven&#39;t provided a Linode API token this step is required to login to your Linode and get the server&#39;s fingerprint either from the welcome message or from the file &lt;code&gt;/etc/opt/simplex/fingerprint&lt;/code&gt; after server starts. See &lt;a href=&quot;https://www.linode.com/docs/guides/use-public-key-authentication-with-ssh/&quot;&gt;Linode&#39;s guide on ssh&lt;/a&gt; .&lt;/li&gt; 
 &lt;li&gt;Deploy your Linode. After it starts wait for SMP server to start and for tags to appear (if a Linode API token was provided). It may take up to 5 minutes depending on the connection speed on the Linode. Connecting Linode IP address to provided domain name may take some additional time.&lt;/li&gt; 
 &lt;li&gt;Get &lt;code&gt;address&lt;/code&gt; and &lt;code&gt;fingerprint&lt;/code&gt; either from Linode tags (click on a tag and copy it&#39;s value from the browser search panel) or via ssh.&lt;/li&gt; 
 &lt;li&gt;Great, your own SMP server is ready! If you provided FQDN use &lt;code&gt;smp://&amp;lt;fingerprint&amp;gt;@&amp;lt;fqdn&amp;gt;&lt;/code&gt; as SMP server address in the client, otherwise use &lt;code&gt;smp://&amp;lt;fingerprint&amp;gt;@&amp;lt;ip_address&amp;gt;&lt;/code&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Please submit an &lt;a href=&quot;https://github.com/simplex-chat/simplexmq/issues&quot;&gt;issue&lt;/a&gt; if any problems occur.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://marketplace.digitalocean.com/apps/simplex-server&quot;&gt;&lt;img alt=&quot;DigitalOcean&quot; src=&quot;https://raw.githubusercontent.com/simplex-chat/simplexmq/stable/img/digitalocean.png&quot; align=&quot;right&quot; width=&quot;300&quot; /&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Deploy SMP server on DigitalOcean&lt;/h2&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;🚧 DigitalOcean snapshot is currently not up to date, it will soon be updated 🏗️&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;* When creating a DigitalOcean account you can use &lt;a href=&quot;https://try.digitalocean.com/freetrialoffer/&quot;&gt;this link&lt;/a&gt; to get free credit. (You would still be required either to provide your credit card details or make a confirmation pre-payment with PayPal)&lt;/p&gt; 
&lt;p&gt;To deploy SMP server use &lt;a href=&quot;https://marketplace.digitalocean.com/apps/simplex-server&quot;&gt;SimpleX Server 1-click app&lt;/a&gt; from DigitalOcean marketplace:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Create a DigitalOcean account or login with an already existing one.&lt;/li&gt; 
 &lt;li&gt;Click &#39;Create SimpleX server Droplet&#39; button.&lt;/li&gt; 
 &lt;li&gt;Choose the region and plan according to your requirements (Basic plan should be sufficient).&lt;/li&gt; 
 &lt;li&gt;Finalize Droplet creation.&lt;/li&gt; 
 &lt;li&gt;Open &quot;Console&quot; on your Droplet management page to get SMP server fingerprint - either from the welcome message or from &lt;code&gt;/etc/opt/simplex/fingerprint&lt;/code&gt;. Alternatively you can manually SSH to created Droplet, see &lt;a href=&quot;https://docs.digitalocean.com/products/droplets/how-to/connect-with-ssh/&quot;&gt;DigitalOcean instruction&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;Great, your own SMP server is ready! Use &lt;code&gt;smp://&amp;lt;fingerprint&amp;gt;@&amp;lt;ip_address&amp;gt;&lt;/code&gt; as SMP server address in the client.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Please submit an &lt;a href=&quot;https://github.com/simplex-chat/simplexmq/issues&quot;&gt;issue&lt;/a&gt; if any problems occur.&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&lt;strong&gt;Please note:&lt;/strong&gt; SMP server uses server address as a Common Name for server certificate generated during initialization. If you would like your server address to be FQDN instead of IP address, you can log in to your Droplet and run the commands below to re-initialize the server. Alternatively you can use &lt;a href=&quot;https://cloud.linode.com/stackscripts/748014&quot;&gt;Linode StackScript&lt;/a&gt; which allows this parameterization.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;smp-server delete
smp-server init [-l] -n &amp;lt;fqdn&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;SMP server design&lt;/h2&gt; 
&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/simplex-chat/simplexmq/stable/design/server.svg?sanitize=true&quot; alt=&quot;SMP server design&quot; /&gt;&lt;/p&gt; 
&lt;h2&gt;SMP agent design&lt;/h2&gt; 
&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/simplex-chat/simplexmq/stable/design/agent2.svg?sanitize=true&quot; alt=&quot;SMP agent design&quot; /&gt;&lt;/p&gt; 
&lt;h2&gt;License&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://raw.githubusercontent.com/simplex-chat/simplexmq/stable/LICENSE&quot;&gt;AGPL v3&lt;/a&gt;&lt;/p&gt;</description>
      
      <media:content url="https://opengraph.githubassets.com/79e1f9ae60df6dbb93cc4b97492a1db226fa28d8f8f09c989c8848605fe699f3/simplex-chat/simplexmq" medium="image" />
      
    </item>
    
    <item>
      <title>halogenandtoast/ArkhamHorror</title>
      <link>https://github.com/halogenandtoast/ArkhamHorror</link>
      <description>&lt;p&gt;An unofficial rules-compliant browser based version of Arkham Horror: The Card Game. Not produced, endorsed, or supported by, or affiliated with Fantasy Flight Games.&lt;/p&gt;&lt;hr&gt;&lt;h1&gt;Arkham Horror LCG&lt;/h1&gt; 
&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/halogenandtoast/ArkhamHorror/main/docs/img/screenshot.png&quot; alt=&quot;Screenshot&quot; /&gt;&lt;/p&gt; 
&lt;p&gt;The goal of this project is to implement a web version of Arkham Horror with as many of the rules implemented as possible.&lt;/p&gt; 
&lt;h2&gt;Warning&lt;/h2&gt; 
&lt;p&gt;This is very much a work in progress. Things may break at any time, but if they do, please file a bug.&lt;/p&gt; 
&lt;h2&gt;Features&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Multiplayer up to 4 players&lt;/li&gt; 
 &lt;li&gt;Multiplayer solitaire&lt;/li&gt; 
 &lt;li&gt;Tarot Readings&lt;/li&gt; 
 &lt;li&gt;Deck import from ArkhamDB and arkham.build&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Finished Content&lt;/h2&gt; 
&lt;h3&gt;Player Cards&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;All player cards before 2026&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Campaigns&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Night of the Zealot 
  &lt;ul&gt; 
   &lt;li&gt;Return to Night of the Zealot&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;The Dunwich Legacy 
  &lt;ul&gt; 
   &lt;li&gt;Return to The Dunwich Legacy&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;The Path To Carcosa 
  &lt;ul&gt; 
   &lt;li&gt;Return to The Path To Carcosa&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;The Forgotten Age 
  &lt;ul&gt; 
   &lt;li&gt;Return to The Forgotten Age&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;The Circle Undone 
  &lt;ul&gt; 
   &lt;li&gt;Return to The Circle Undone&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;The Dream-Eaters&lt;/li&gt; 
 &lt;li&gt;The Innsmouth Conspiracy&lt;/li&gt; 
 &lt;li&gt;Edge of the Earth&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Side Stories&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;The Curse of the Rougarou&lt;/li&gt; 
 &lt;li&gt;Carnevale of Horrors&lt;/li&gt; 
 &lt;li&gt;Murder at the Excelsior Hotel&lt;/li&gt; 
 &lt;li&gt;The Midwinter Gala&lt;/li&gt; 
 &lt;li&gt;Film Fatale&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;I just want to try this out on my computer&lt;/h2&gt; 
&lt;h3&gt;Linux Users&lt;/h3&gt; 
&lt;p&gt;Install &lt;a href=&quot;https://www.docker.com/&quot;&gt;Docker&lt;/a&gt;, then run:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;curl -fsSL https://raw.githubusercontent.com/halogenandtoast/ArkhamHorror/main/install.sh | bash
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This creates an &lt;code&gt;arkham-horror/&lt;/code&gt; directory, downloads the required files, generates a database password, and starts the app. Open &lt;a href=&quot;http://localhost:3000&quot;&gt;http://localhost:3000&lt;/a&gt; when it&#39;s done.&lt;/p&gt; 
&lt;p&gt;The script will ask if you want to download game images (~2.9 GB). If you skip this step, the app loads images from the CDN automatically — no extra setup needed.&lt;/p&gt; 
&lt;h3&gt;Windows Users&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Install Docker, specifically the version of Docker known as &lt;a href=&quot;https://docs.docker.com/desktop/&quot;&gt;Docker Desktop&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;Install a &quot;terminal only&quot; version of Ubuntu that can be run inside of Windows, for which the easiest available method is to &lt;a href=&quot;https://documentation.ubuntu.com/wsl/latest/howto/install-ubuntu-wsl2/#method-3-install-from-the-microsoft-store&quot;&gt;install from the Microsoft Store&lt;/a&gt;. You may choose any Linux distro other than Ubuntu if you know what you are doing.&lt;/li&gt; 
 &lt;li&gt;In Docker Desktop, go to &lt;code&gt;Settings &amp;gt; Resources &amp;gt; WSL Integration&lt;/code&gt; and enable integration with Ubuntu Linux distro that you installed in the previous step. This allows us to access Docker from inside Ubuntu.&lt;/li&gt; 
 &lt;li&gt;Start the Ubuntu terminal and run:&lt;pre&gt;&lt;code&gt;curl -fsSL https://raw.githubusercontent.com/halogenandtoast/ArkhamHorror/main/install.sh | bash
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt;The app should start being served at &lt;a href=&quot;http://localhost:3000&quot;&gt;http://localhost:3000&lt;/a&gt;, if nothing went wrong.&lt;/li&gt; 
 &lt;li&gt;Every time you want to start the app, you can use &lt;code&gt;docker compose up&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;If you get around to figuring out how to use Docker Desktop, you could also press buttons to start and stop the app instead of typing commands to run it.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Things that can go wrong&lt;/h4&gt; 
&lt;p&gt;If the app doesnt start at all, or it starts but you cannot create a user account, or any other issue due to Murphy&#39;s Law, you have to check the logs of the Docker container to find the error messages. In Docker Desktop, you can access this by clicking on the &lt;code&gt;arkham-horror&lt;/code&gt; &quot;compose stack&quot; found in the &lt;code&gt;Containers&lt;/code&gt; list.&lt;/p&gt; 
&lt;p&gt;Possible problems:&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt; 
   &lt;th&gt;Problem&lt;/th&gt; 
   &lt;th&gt;Solution&lt;/th&gt; 
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Error involving &lt;code&gt;docker-credential-desktop.exe&lt;/code&gt;&lt;/td&gt; 
   &lt;td&gt;Try restarting your computer&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;When clicking on the &quot;REGISTER&quot; button, the error &lt;code&gt;password authentication failed&lt;/code&gt; is logged&lt;/td&gt; 
   &lt;td&gt;Stop the app using &lt;code&gt;docker compose down&lt;/code&gt; and then refetch the app using &lt;code&gt;docker compose pull&lt;/code&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h3&gt;Manual setup (alternative)&lt;/h3&gt; 
&lt;p&gt;If you prefer not to use the install script, you&#39;ll need four files:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;mkdir -p arkham-horror/config arkham-horror/scripts arkham-horror/frontend/public/img
cd arkham-horror
curl -fsSL https://raw.githubusercontent.com/halogenandtoast/ArkhamHorror/main/docker-compose.yml -o docker-compose.yml
curl -fsSL https://raw.githubusercontent.com/halogenandtoast/ArkhamHorror/main/setup.sql -o setup.sql
curl -fsSL https://raw.githubusercontent.com/halogenandtoast/ArkhamHorror/main/scripts/fetch-assets.sh -o scripts/fetch-assets.sh
# Generate a strong password
openssl rand -base64 32 &amp;gt; config/postgres_password.txt
docker compose up -d
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The app automatically detects whether local images are present:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;No local images&lt;/strong&gt; (default after install) → images load from the CDN automatically&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Local images present&lt;/strong&gt; (after running the fetch service) → images served locally&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;To fetch images locally, use the &lt;code&gt;fetch-images&lt;/code&gt; Docker service. Once fetched, restart with &lt;code&gt;docker compose restart web&lt;/code&gt; and the app will switch to local images.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;# English only (~1.3 GB) — portraits, tokens, icons, card images
docker compose --profile fetch-images run --rm fetch-images en

# English + a specific language (recommended for non-English play)
docker compose --profile fetch-images run --rm fetch-images en+fr   # French
docker compose --profile fetch-images run --rm fetch-images en+es   # Spanish
docker compose --profile fetch-images run --rm fetch-images en+ita  # Italian
docker compose --profile fetch-images run --rm fetch-images en+ko   # Korean
docker compose --profile fetch-images run --rm fetch-images en+zh   # Chinese

# A single language&#39;s card translations only (English assets still load from CDN)
docker compose --profile fetch-images run --rm fetch-images fr

# Everything (~2.9 GB)
docker compose --profile fetch-images run --rm fetch-images all
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Images are stored in &lt;code&gt;frontend/public/img/&lt;/code&gt; and mounted into the container. After fetching, run &lt;code&gt;docker compose restart web&lt;/code&gt; to pick them up.&lt;/p&gt; 
&lt;p&gt;To switch back to CDN at any time, add this to the &lt;code&gt;web&lt;/code&gt; service environment in &lt;code&gt;docker-compose.yml&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;    environment:
      - ASSET_HOST=https://assets.arkhamhorror.app
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Updating&lt;/h3&gt; 
&lt;pre&gt;&lt;code&gt;docker compose pull
docker compose up -d
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Local dev&lt;/h2&gt; 
&lt;h3&gt;Dependencies&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Stack for GHC&lt;/li&gt; 
 &lt;li&gt;Node&lt;/li&gt; 
 &lt;li&gt;Postgresql&lt;/li&gt; 
 &lt;li&gt;Sqitch (optional: for migrations)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Local Setup&lt;/h3&gt; 
&lt;h4&gt;Running via Docker&lt;/h4&gt; 
&lt;p&gt;The image is setup to use an external database passed via the &lt;code&gt;DATABASE_URL&lt;/code&gt; environment variable. Follow the steps below to setup the database and then run the following commands&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;docker build -t arkham .
docker run -t -i -e PORT=3000 -e DATABASE_URL=&quot;postgres://docker:docker@host.docker.internal:5432/arkham-horror-backend&quot; -p 3000:3000 arkham
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;Backend&lt;/h4&gt; 
&lt;p&gt;Run &lt;code&gt;stack setup&lt;/code&gt; in the &lt;code&gt;backend&lt;/code&gt; directory, then run &lt;code&gt;stack build --fast&lt;/code&gt; (note: this will still take a long time)&lt;/p&gt; 
&lt;h4&gt;Frontend&lt;/h4&gt; 
&lt;p&gt;Run &lt;code&gt;npm install&lt;/code&gt; in the &lt;code&gt;frontend&lt;/code&gt; directory&lt;/p&gt; 
&lt;h4&gt;Images&lt;/h4&gt; 
&lt;p&gt;Image assets (~2.9 GB) are &lt;strong&gt;not stored in the git repository&lt;/strong&gt;. They are hosted on CloudFront and the app loads them from the CDN by default in both development and production — no extra setup needed.&lt;/p&gt; 
&lt;p&gt;If you need local copies (e.g. for offline development), use the fetch script (requires &lt;code&gt;aws&lt;/code&gt; CLI and &lt;code&gt;curl&lt;/code&gt;):&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;make fetch-images     # Everything (~2.9 GB)
make fetch-cards      # English card images only (~755 MB)

# Or use the script directly:
./scripts/fetch-assets.sh en        # All English/static images (~1.3 GB)
./scripts/fetch-assets.sh en+fr     # English + French (recommended for French play)
./scripts/fetch-assets.sh en+es     # English + Spanish
./scripts/fetch-assets.sh en+ita    # English + Italian
./scripts/fetch-assets.sh en+ko     # English + Korean
./scripts/fetch-assets.sh en+zh     # English + Chinese
./scripts/fetch-assets.sh fr        # French card translations only
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;If you only have Docker (no local AWS CLI), use the Docker-based targets instead:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;make fetch-images-docker    # Everything via Docker (~2.9 GB)
make fetch-cards-docker     # English card images only via Docker

# Or run directly with the same targets as above:
docker compose --profile fetch-images run --rm fetch-images en
docker compose --profile fetch-images run --rm fetch-images en+fr
docker compose --profile fetch-images run --rm fetch-images fr
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;To use local images instead of CDN in local dev, create &lt;code&gt;frontend/.env.development.local&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;VITE_ASSET_HOST=
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;To revert to CDN, remove the file or set &lt;code&gt;VITE_ASSET_HOST=https://assets.arkhamhorror.app&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;If you add new images, sync them to S3 and regenerate the manifest:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;make sync-and-manifest
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;To install a git hook that warns if you forget to update the manifest:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;make install-hooks
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;Database&lt;/h4&gt; 
&lt;p&gt;Create the local database:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;createdb arkham-horror-backend
cd migrations
sqitch deploy db:pg:arkham-horror-backend
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;If you do not have sqitch you can &lt;code&gt;cat migrations/deploy/*&lt;/code&gt; to see the create table statements and run them manually, you will want to specifically run the &lt;code&gt;users&lt;/code&gt; and &lt;code&gt;arkham_games&lt;/code&gt; create table statements first.&lt;/p&gt; 
&lt;h3&gt;Running the server&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;start the backend with &lt;code&gt;cd backend &amp;amp;&amp;amp; make api.watch&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;start the frontend with &lt;code&gt;cd frontend &amp;amp;&amp;amp; npm run serve&lt;/code&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Copyright Disclaimer&lt;/h2&gt; 
&lt;p&gt;The information presented in this app about &lt;a href=&quot;https://www.fantasyflightgames.com/en/products/arkham-horror-the-card-game/&quot;&gt;Arkham Horror: The Card Game™&lt;/a&gt;, both textual and graphical, is © Fantasy Flight Games 2024. This app is a fan project and is not produced, endorsed, or supported by, or affiliated with Fantasy Flight Games.&lt;/p&gt; 
&lt;p&gt;All artwork and illustrations are the intellectual property of their respective creators. All Arkham Horror: The Card Game™ images and graphics are copyrighted by Fantasy Flight Games.&lt;/p&gt;</description>
      
      <media:content url="https://opengraph.githubassets.com/821598abbdb480605217e7b4dc14b201c9f7a88b40e721f9cbe7bb262089fdbc/halogenandtoast/ArkhamHorror" medium="image" />
      
    </item>
    
    <item>
      <title>maralorn/nix-output-monitor</title>
      <link>https://github.com/maralorn/nix-output-monitor</link>
      <description>&lt;p&gt;Pipe your nix-build output through the nix-output-monitor a.k.a nom to get additional information while building.&lt;/p&gt;&lt;hr&gt;&lt;h1&gt;nix-output-monitor&lt;/h1&gt; 
&lt;p&gt;Pipe your nix-build output through the nix-output-monitor (aka nom) to get additional information while building.&lt;/p&gt; 
&lt;p&gt;While your build runs, nom will draw something like this at the bottom of your build log:&lt;/p&gt; 
&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/maralorn/nix-output-monitor/main/example-screenshot.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;(note that to reduce clutter nom only shows timers over 1s build or download time.)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://repology.org/project/nix-output-monitor/versions&quot;&gt;&lt;img src=&quot;https://repology.org/badge/vertical-allrepos/nix-output-monitor.svg?sanitize=true&quot; alt=&quot;Packaging status&quot; /&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Status&lt;/h2&gt; 
&lt;p&gt;This was an experiment to write something fun and useful in Haskell, which proved to be useful to quite a lot of people. By now, nom is quite fully featured with support for nix v1 commands (e.g. &lt;code&gt;nix-build&lt;/code&gt;) and nix v2 command (e.g. &lt;code&gt;nix build&lt;/code&gt;). At this point it seems like I will maintain nom until better UX options for nix arrive.&lt;/p&gt; 
&lt;p&gt;You are free and &lt;strong&gt;very welcome to contribute feedback, issues or PRs&lt;/strong&gt;. Issues and pull requests can be opened at &lt;strong&gt;&lt;a href=&quot;https://github.com/maralorn/nix-output-monitor&quot;&gt;GitHub&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Source and releases&lt;/strong&gt; are available from &lt;strong&gt;&lt;a href=&quot;https://code.maralorn.de/maralorn/nix-output-monitor/releases&quot;&gt;code.maralorn.de&lt;/a&gt;&lt;/strong&gt;. Starting from version 2.1.0, nom follows the &lt;a href=&quot;https://semver&quot;&gt;SemVer&lt;/a&gt; versioning scheme. The versioning applies to the behavior of the executable. There are no stability guarantees for the library component in the cabal project.&lt;/p&gt; 
&lt;h2&gt;Support&lt;/h2&gt; 
&lt;p&gt;If your question is not answered in this README you can ask it in &lt;a href=&quot;https://matrix.to/#/#nix-output-monitor:maralorn.de&quot;&gt;#nix-output-monitor:maralorn.de&lt;/a&gt; on matrix or open an issue on github.&lt;/p&gt; 
&lt;h2&gt;Installing&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;nixpkgs: nom is in nixpkgs. Just install &lt;code&gt;pkgs.nix-output-monitor&lt;/code&gt; in the usual way. You might want to install it from nixos-unstable to get the newest version.&lt;/li&gt; 
 &lt;li&gt;cabal: Install &lt;code&gt;cabal-install&lt;/code&gt; and run &lt;code&gt;cabal install&lt;/code&gt; in the checked out repo.&lt;/li&gt; 
 &lt;li&gt;nix: or use &lt;code&gt;nix build&lt;/code&gt; or &lt;code&gt;nix-env&lt;/code&gt; or include the flake output of this repo in your nixos config.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Running&lt;/h2&gt; 
&lt;h3&gt;The Easy Way&lt;/h3&gt; 
&lt;p&gt;&lt;strong&gt;Warning:&lt;/strong&gt; The displayed build tree might be incomplete with new-style commands like &lt;code&gt;nix build&lt;/code&gt; for nix versions &amp;lt;2.10.&lt;/p&gt; 
&lt;p&gt;The &lt;code&gt;nom&lt;/code&gt; binary (starting from version 2.0) behaves as a &lt;code&gt;nix&lt;/code&gt; drop in, with much more colorful output, but &lt;strong&gt;only&lt;/strong&gt; for the following commands:&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;nom build &amp;lt;args&amp;gt;&lt;/code&gt;: Behaves like &lt;code&gt;nix build &amp;lt;args&amp;gt;&lt;/code&gt;.&lt;br /&gt; &lt;code&gt;nom shell &amp;lt;args&amp;gt;&lt;/code&gt;: Behaves like &lt;code&gt;nix shell &amp;lt;args&amp;gt;&lt;/code&gt;.&lt;br /&gt; &lt;code&gt;nom develop &amp;lt;args&amp;gt;&lt;/code&gt;: Behaves like &lt;code&gt;nix develop &amp;lt;args&amp;gt;&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;The latter two commands work by calling &lt;code&gt;nix shell&lt;/code&gt; or &lt;code&gt;nix develop&lt;/code&gt; twice, the first time with overridden &lt;code&gt;--run exit&lt;/code&gt; and monitoring the output, the second time passing output through to the user. This will incur a performance cost by doubling eval time.&lt;/p&gt; 
&lt;p&gt;Furthermore when called via the corresponding provided symlinks, nom is also a drop-in for the following commands:&lt;br /&gt; &lt;code&gt;nom-build &amp;lt;args&amp;gt;&lt;/code&gt;: Behaves like &lt;code&gt;nix-build &amp;lt;args&amp;gt;&lt;/code&gt;.&lt;br /&gt; &lt;code&gt;nom-shell &amp;lt;args&amp;gt;&lt;/code&gt;: Behaves like &lt;code&gt;nix-shell &amp;lt;args&amp;gt;&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;All aliases internally use the json-based approach (see next section) and propagate error codes. If you want nom support for other nix commands please open an issue.&lt;/p&gt; 
&lt;h3&gt;The Flexible Way&lt;/h3&gt; 
&lt;h4&gt;JSON based&lt;/h4&gt; 
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;nix-build --log-format internal-json -v |&amp;amp; nom --json
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Warning:&lt;/strong&gt; Don‘t forget to redirect stderr. That&#39;s what the &lt;code&gt;&amp;amp;&lt;/code&gt;, does.&lt;/p&gt; 
&lt;h4&gt;Human readable log parsing&lt;/h4&gt; 
&lt;p&gt;It is highly recommended to always append &lt;code&gt;--log-format internal-json -v&lt;/code&gt; (or use the above mentioned aliases.) and call &lt;code&gt;nom&lt;/code&gt; with &lt;code&gt;--json&lt;/code&gt;. That will give you much more informative output.&lt;/p&gt; 
&lt;p&gt;If you are in a situation, where you can‘t use the json based nix output you can still use&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;nix-build |&amp;amp; nom
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Warning:&lt;/strong&gt; Don‘t forget to redirect stderr. That&#39;s what the &lt;code&gt;&amp;amp;&lt;/code&gt;, does.&lt;/p&gt; 
&lt;p&gt;This has the advantage to also work with other commands like &lt;code&gt;nixos-rebuild&lt;/code&gt; or &lt;code&gt;home-manager&lt;/code&gt;, where it is not trivial to pass in the &lt;code&gt;--log-format internal-json -v&lt;/code&gt; flag. nom will pass everything it reads through, if it does not understand it. This makes it ideal to attach it to scripts which output more than just &lt;code&gt;nix&lt;/code&gt; output.&lt;/p&gt; 
&lt;h3&gt;Preserving Colored Text&lt;/h3&gt; 
&lt;p&gt;Colored text will work as expected in json-mode.&lt;/p&gt; 
&lt;p&gt;In human-readable log mode you can preserve the color of the redirected text by using the &lt;code&gt;unbuffer&lt;/code&gt; command from the &lt;code&gt;expect&lt;/code&gt; package.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;unbuffer nix-build |&amp;amp; nom
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Explanation&lt;/h2&gt; 
&lt;h3&gt;Legend&lt;/h3&gt; 
&lt;p&gt;Nom tries to convey information via symbols and colors&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;⏵&lt;/code&gt;, yellow: running builds&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;✔&lt;/code&gt;, green: completed builds&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;⏸&lt;/code&gt;, blue: planned builds&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;⚠&lt;/code&gt;, red: failed builds&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;↓ ⏵&lt;/code&gt;, yellow: running downloads&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;↑ ⏵&lt;/code&gt;, yellow: running uploads&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;↓ ✔&lt;/code&gt;, green: completed downloads&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;↑ ✔&lt;/code&gt;, green: completed uploads&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;↓ ⏸&lt;/code&gt;, blue: waiting downloads&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;∅&lt;/code&gt;: the mean duration of the 10 last builds of derivations with the same name after the hash&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;⏱︎&lt;/code&gt;: running time&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;∑&lt;/code&gt;: a summary over all packages and hosts&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;If you can‘t see all icons you may need another terminal font. I recommend any font from &lt;code&gt;pkgs.nerdfonts&lt;/code&gt; e.g. &lt;code&gt;&quot;JetBrainsMono Nerd Font&quot;&lt;/code&gt;. Also different terminals might work differently well. I recommend: &lt;code&gt;pkgs.foot&lt;/code&gt;.&lt;/p&gt; 
&lt;h3&gt;How to Read the Dependency Graph&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Every entry in the nom tree stands for one derivation.&lt;/li&gt; 
 &lt;li&gt;Children of a node are direct dependencies.&lt;/li&gt; 
 &lt;li&gt;nom will try to show you the most relevant part of the dependency tree, roughly aiming to fill a third of your terminal&lt;/li&gt; 
 &lt;li&gt;No build will be printed twice in the tree, it will only be shown for the lowermost dependency.&lt;/li&gt; 
 &lt;li&gt;nom will do it’s best to print all running or failed builds, downloads and uploads, but it does not print every direct child of a node.&lt;/li&gt; 
 &lt;li&gt;Use the colors from above to read the summary&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Example Runs&lt;/h2&gt; 
&lt;p&gt;An example remote build: &lt;a href=&quot;https://asciinema.org/a/KwCh38ujQ9wusHw8kyW4KCMZo&quot;&gt;&lt;img src=&quot;https://asciinema.org/a/KwCh38ujQ9wusHw8kyW4KCMZo.svg?sanitize=true&quot; alt=&quot;asciicast&quot; /&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;An example with a lot of downloads: &lt;a href=&quot;https://asciinema.org/a/7hJXH2iFLEkKxG1lL25lspqNn&quot;&gt;&lt;img src=&quot;https://asciinema.org/a/7hJXH2iFLEkKxG1lL25lspqNn.svg?sanitize=true&quot; alt=&quot;asciicast&quot; /&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Implementation&lt;/h2&gt; 
&lt;p&gt;Right now nom uses four sources of information:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;The parsed nix-build output (json or human-readable)&lt;/li&gt; 
 &lt;li&gt;it checks if build results exist in the nix-store (only in human-readable mode)&lt;/li&gt; 
 &lt;li&gt;it queries &lt;code&gt;.drv&lt;/code&gt; files for information about the &lt;code&gt;out&lt;/code&gt; output path.&lt;/li&gt; 
 &lt;li&gt;It caches build times in &lt;code&gt;$XDG_STATE_HOME/nix-output-monitor/build-reports.csv&lt;/code&gt;.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;h2&gt;Limitations&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;This will fail in unexpected and expected ways.&lt;/li&gt; 
 &lt;li&gt;Luckily I don‘t think this program screws up anything more than your terminal.&lt;/li&gt; 
 &lt;li&gt;remote builds will sometimes be shown as running even when they are actually still waiting for uploads or downloads. This is how nix reports it.&lt;/li&gt; 
 &lt;li&gt;Terminal clearing and reprinting is brittle. It might fail with your terminal or terminal width. But at this point I‘ve invested some effort to make it usable.&lt;/li&gt; 
 &lt;li&gt;This program also makes assumptions like your nix-store is at &quot;/nix/store&quot;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;For human-readable log parsing mode:&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;nix-output-monitor receives most its information from parsing nix-build output. The parser might be too strict or too loose for use cases I didn‘t think of. Then &lt;strong&gt;the numbers displayed will be off&lt;/strong&gt;!&lt;/li&gt; 
 &lt;li&gt;nix-build does not show information when a download or upload is finished, so we currently cannot differentiate between started and completed downloads.&lt;/li&gt; 
 &lt;li&gt;For completed build detection we assume that every derivation has an output called &quot;out&quot;.&lt;/li&gt; 
&lt;/ul&gt;</description>
      
      <media:content url="https://opengraph.githubassets.com/aa6c942e0de765a941aa63d9a54149cd6c7858848627eeef89c1ff89f19c33d5/maralorn/nix-output-monitor" medium="image" />
      
    </item>
    
  </channel>
</rss>
