<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Bilal Bentoumi</title>
    <description>The latest articles on DEV Community by Bilal Bentoumi (@bilalbentoumi).</description>
    <link>https://dev.to/bilalbentoumi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F708512%2F4a5b6b14-0e6d-4523-b201-34d7587ea8e6.jpeg</url>
      <title>DEV Community: Bilal Bentoumi</title>
      <link>https://dev.to/bilalbentoumi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bilalbentoumi"/>
    <language>en</language>
    <item>
      <title>🚀 Showcasing hostly — a terminal tool for local domains with HTTPS (no config files, no pain)</title>
      <dc:creator>Bilal Bentoumi</dc:creator>
      <pubDate>Sun, 21 Jun 2026 21:57:39 +0000</pubDate>
      <link>https://dev.to/bilalbentoumi/showcasing-hostly-a-terminal-tool-for-local-domains-with-https-no-config-files-no-pain-179a</link>
      <guid>https://dev.to/bilalbentoumi/showcasing-hostly-a-terminal-tool-for-local-domains-with-https-no-config-files-no-pain-179a</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F361x8eq3yxd7dk46uvar.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F361x8eq3yxd7dk46uvar.png" alt=" " width="800" height="476"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you’ve ever worked on multiple local services, you’ve probably done this dance:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;edit &lt;code&gt;/etc/hosts&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;run a reverse proxy (Caddy / Nginx)&lt;/li&gt;
&lt;li&gt;generate HTTPS certs with mkcert&lt;/li&gt;
&lt;li&gt;fix broken configs after reboot&lt;/li&gt;
&lt;li&gt;repeat for every project&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I got tired of that.&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;hostly&lt;/strong&gt; — a terminal-first tool that manages local development domains with HTTPS, reverse proxying, and persistence in one place.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 What is hostly?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;hostly&lt;/strong&gt; is an interactive terminal app for managing local development domains on macOS and Linux.&lt;/p&gt;

&lt;p&gt;It lets you map friendly domains like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;https://app.local
https://api.local
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to local ports like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;localhost:3000
localhost:8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔐 Trusted HTTPS (green padlock)&lt;/li&gt;
&lt;li&gt;🔁 Reverse proxy via Caddy&lt;/li&gt;
&lt;li&gt;🧩 Automatic &lt;code&gt;/etc/hosts&lt;/code&gt; management&lt;/li&gt;
&lt;li&gt;🔄 Persistent routing across reboots&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚙️ The problem it solves
&lt;/h2&gt;

&lt;p&gt;A typical local setup looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.local → /etc/hosts → localhost → proxy → your app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But in reality:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/etc/hosts&lt;/code&gt; is manual and error-prone&lt;/li&gt;
&lt;li&gt;Caddy config resets unless carefully managed&lt;/li&gt;
&lt;li&gt;HTTPS locally is annoying to maintain&lt;/li&gt;
&lt;li&gt;restarting your machine breaks everything&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So developers end up duct-taping tools together.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✨ What hostly does differently
&lt;/h2&gt;

&lt;p&gt;Instead of managing 4 different systems manually, hostly introduces a single source of truth.&lt;/p&gt;




&lt;h2&gt;
  
  
  🖥️ One terminal UI
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hostly
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A full-screen interactive interface:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add/edit domains&lt;/li&gt;
&lt;li&gt;Map ports&lt;/li&gt;
&lt;li&gt;Choose HTTP / HTTPS&lt;/li&gt;
&lt;li&gt;Manage certificates&lt;/li&gt;
&lt;li&gt;Control daemon syncing&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔐 HTTPS that just works
&lt;/h2&gt;

&lt;p&gt;hostly uses Caddy’s internal CA to issue trusted certificates locally.&lt;/p&gt;

&lt;p&gt;So instead of:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Not Secure ⚠️”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You get:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://app.local" rel="noopener noreferrer"&gt;https://app.local&lt;/a&gt; ✔️ (trusted)&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🔁 Automatic reverse proxying
&lt;/h2&gt;

&lt;p&gt;Each domain is pushed to Caddy via its admin API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.local → 127.0.0.1:3000
api.local → 127.0.0.1:8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No config files to touch manually.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧩 Safe &lt;code&gt;/etc/hosts&lt;/code&gt; management
&lt;/h2&gt;

&lt;p&gt;hostly only modifies a managed block:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="c"&gt;# Hostly Start
&lt;/span&gt;&lt;span class="m"&gt;127&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;.&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;.&lt;span class="n"&gt;local&lt;/span&gt;
&lt;span class="c"&gt;# Hostly End
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything else stays untouched.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔄 Boot persistence (daemon)
&lt;/h2&gt;

&lt;p&gt;Caddy loses dynamic routes after restart.&lt;/p&gt;

&lt;p&gt;So hostly includes a sync system:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hostly &lt;span class="nb"&gt;sync&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And optional boot daemon:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;macOS → launchd&lt;/li&gt;
&lt;li&gt;Linux → systemd user service&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It restores everything automatically.&lt;/p&gt;




&lt;h2&gt;
  
  
  📦 Installation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Requirements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Node.js ≥ 18&lt;/li&gt;
&lt;li&gt;Caddy installed&lt;/li&gt;
&lt;li&gt;macOS or Linux&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Install
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; hostly
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install Caddy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;caddy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🚀 Usage
&lt;/h2&gt;

&lt;p&gt;Start the app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hostly
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add a domain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Host: &lt;code&gt;app.local&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Port: &lt;code&gt;3000&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Scheme: &lt;code&gt;https&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then open:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://app.local
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Done.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧩 How it works (simplified)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Browser
  ↓
/etc/hosts (resolves domain)
  ↓
Caddy (HTTPS + reverse proxy)
  ↓
Your app (localhost:3000)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;hostly is the glue that keeps everything in sync.&lt;/p&gt;




&lt;h2&gt;
  
  
  🖥️ Tech stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Ink (React for CLI UI)&lt;/li&gt;
&lt;li&gt;Zustand (state management)&lt;/li&gt;
&lt;li&gt;Caddy (reverse proxy + HTTPS)&lt;/li&gt;
&lt;li&gt;Node.js&lt;/li&gt;
&lt;li&gt;systemd / launchd integration&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  💡 Why I built it
&lt;/h2&gt;

&lt;p&gt;I wanted a local dev environment where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I don’t touch config files repeatedly&lt;/li&gt;
&lt;li&gt;HTTPS works by default&lt;/li&gt;
&lt;li&gt;domains feel real (&lt;code&gt;app.local&lt;/code&gt;, not &lt;code&gt;localhost:3000&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;everything survives restarts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So I turned it into a CLI tool.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧪 Try it out
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; hostly
hostly
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  📌 Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;npm: &lt;a href="https://www.npmjs.com/package/hostly" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/hostly&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/bilalbentoumi/hostly" rel="noopener noreferrer"&gt;https://github.com/bilalbentoumi/hostly&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;License: MIT&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🙌 Feedback welcome
&lt;/h2&gt;

&lt;p&gt;This is still early, and I’m actively improving it.&lt;/p&gt;

&lt;p&gt;Feedback is welcome around:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CLI UX&lt;/li&gt;
&lt;li&gt;missing features&lt;/li&gt;
&lt;li&gt;developer workflow improvements&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>tooling</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
