<?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: Blaine</title>
    <description>The latest articles on DEV Community by Blaine (@blainesensei).</description>
    <link>https://dev.to/blainesensei</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F251965%2F6fc93e7c-ac91-459e-bcea-f0bb3d6a5519.jpg</url>
      <title>DEV Community: Blaine</title>
      <link>https://dev.to/blainesensei</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/blainesensei"/>
    <language>en</language>
    <item>
      <title>[Boost]</title>
      <dc:creator>Blaine</dc:creator>
      <pubDate>Fri, 13 Mar 2026 19:22:09 +0000</pubDate>
      <link>https://dev.to/blainesensei/-1pj7</link>
      <guid>https://dev.to/blainesensei/-1pj7</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/blainesensei" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F251965%2F6fc93e7c-ac91-459e-bcea-f0bb3d6a5519.jpg" alt="blainesensei"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/blainesensei/huntos-an-automated-job-application-tool-and-my-experience-vibe-coding-1ie" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;HuntOS: an automated job application tool; and my experience vibe coding&lt;/h2&gt;
      &lt;h3&gt;Blaine ・ Mar 13&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#ai&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#automation&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#vibecoding&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#opensource&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>ai</category>
      <category>automation</category>
      <category>vibecoding</category>
      <category>opensource</category>
    </item>
    <item>
      <title>HuntOS: an automated job application tool; and my experience vibe coding</title>
      <dc:creator>Blaine</dc:creator>
      <pubDate>Fri, 13 Mar 2026 19:04:49 +0000</pubDate>
      <link>https://dev.to/blainesensei/huntos-an-automated-job-application-tool-and-my-experience-vibe-coding-1ie</link>
      <guid>https://dev.to/blainesensei/huntos-an-automated-job-application-tool-and-my-experience-vibe-coding-1ie</guid>
      <description>&lt;p&gt;A few months ago, a close friend of mine lost his job. The kicker? He wasn't just laid off; he was essentially replaced by an AI programming agent. It was a wake-up call. I wanted to understand exactly where my own profile fit in this rapidly shifting market, but the manual process of searching and applying is a soul-crushing grind.&lt;/p&gt;

&lt;p&gt;At the same time, my day job involved a lot of work with browser automation and form-filling. I realized I could combine these two worlds. &lt;/p&gt;

&lt;p&gt;The result is &lt;strong&gt;HuntOS&lt;/strong&gt;: a local-first, automated job application tool. But the real story isn't just what it does—it's how it was built.&lt;/p&gt;

&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%2Fimages.unsplash.com%2Fphoto-1762330463293-babc1c6e43ea%3Fq%3D80%26w%3D2070%26auto%3Dformat%26fit%3Dcrop%26ixlib%3Drb-4.1.0%26ixid%3DM3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%253D%253D" 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%2Fimages.unsplash.com%2Fphoto-1762330463293-babc1c6e43ea%3Fq%3D80%26w%3D2070%26auto%3Dformat%26fit%3Dcrop%26ixlib%3Drb-4.1.0%26ixid%3DM3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%253D%253D" alt="The manual application grind"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The $10 Stack: Vibe Coding into Reality
&lt;/h2&gt;

&lt;p&gt;This project is a testament to how "vibe coding" has changed the game. I built HuntOS with just a $10 GitHub Copilot subscription, the Zed editor, and a dream. &lt;/p&gt;

&lt;p&gt;When I say I "built" it, I mean I didn't manually write a single line of code. &lt;/p&gt;

&lt;p&gt;Using the AI features in Zed, I acted more like a systems architect than a coder. I provided the high-level design, described the infrastructure, and let the agents do the heavy lifting. I primarily used &lt;strong&gt;Claude 3.5 Sonnet&lt;/strong&gt; for the bulk of the logic and &lt;strong&gt;Claude 3 Opus&lt;/strong&gt; for the more complex architectural puzzles. &lt;/p&gt;

&lt;p&gt;Even the logo you see at the top of the README? That was vibe-coded as an SVG. I described the look I wanted, and the agent generated the math and the tags.&lt;/p&gt;

&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.amazonaws.com%2Fuploads%2Farticles%2F64vg5ci5m4bugnw4j8cs.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.amazonaws.com%2Fuploads%2Farticles%2F64vg5ci5m4bugnw4j8cs.png" alt="Screenshot of the SVG code and the rendered logo along with zed chat"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Recipe: How to Replicate This Success
&lt;/h2&gt;

&lt;p&gt;If you want to build something similar, here is the "cooking recipe" I followed. It’s less about syntax and more about managing context:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Blueprint:&lt;/strong&gt; I started with a high-level &lt;a href="https://github.com/Blakeinstein/HuntOS/blob/main/DESIGN.md" rel="noopener noreferrer"&gt;DESIGN.md&lt;/a&gt;. This served as the source of truth for the entire system.&lt;br&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.amazonaws.com%2Fuploads%2Farticles%2F5g3orxllw62r5vsqmlt1.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.amazonaws.com%2Fuploads%2Farticles%2F5g3orxllw62r5vsqmlt1.png" alt="Preview for the master Design Document"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Specs:&lt;/strong&gt; From that blueprint, I generated individual technical specs inside a &lt;a href="https://github.com/Blakeinstein/HuntOS/tree/main/Design" rel="noopener noreferrer"&gt;Design folder&lt;/a&gt;. Each file focused on a specific sub-system.&lt;br&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.amazonaws.com%2Fuploads%2Farticles%2Fmms57btgexqnki5uqpvh.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.amazonaws.com%2Fuploads%2Farticles%2Fmms57btgexqnki5uqpvh.png" alt="Preview of the folder containing the Design Specifications"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Agents:&lt;/strong&gt; For every new feature, I created a new Zed Agent.&lt;br&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.amazonaws.com%2Fuploads%2Farticles%2Fckzpopqyxohwz2rvpn4d.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.amazonaws.com%2Fuploads%2Farticles%2Fckzpopqyxohwz2rvpn4d.png" alt="Screenshot of the Zed Editor with agent panel open"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Context Management:&lt;/strong&gt; I grouped similar features into the same chat histories. When a chat reached its context limit, I would have the agent summarize the current state, start a new agent session with that summary, and continue. This kept the "brain" focused on the task at hand without getting lost in the noise of unrelated features.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Workflow:&lt;/strong&gt; This following video 

  &lt;iframe src="https://www.youtube.com/embed/wEsjK3Smovw"&gt;
  &lt;/iframe&gt;


 perfectly encapsulates the workflow I used. Even though I didn't see it until after I started, it’s a great visual guide for this style of development.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The most shocking part? The total time investment was about &lt;strong&gt;2 weeks with multiple gaps&lt;/strong&gt;. In reality, it was roughly &lt;strong&gt;4 days of work, 2 hours per day&lt;/strong&gt;. That’s 8 hours to go from a dream to a working automated job application OS.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is HuntOS?
&lt;/h2&gt;

&lt;p&gt;HuntOS is designed to be your personal career command center. It handles the tedious parts of the job search so you can focus on the interviews.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Job Board Scraping:&lt;/strong&gt; It pulls listings from LinkedIn, Greenhouse, and others.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tailored Resumes:&lt;/strong&gt; It uses agents to generate Markdown and PDF resumes specifically for each job description.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Browser Automation:&lt;/strong&gt; Using Chrome DevTools Protocol (CDP), it actually navigates to the forms and fills them out.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audit Trails:&lt;/strong&gt; It takes screenshots of every step the agent takes, so you can see exactly what happened during an automated application.&lt;/li&gt;
&lt;/ul&gt;

&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.amazonaws.com%2Fuploads%2Farticles%2F802xth2a5431oyz5m03d.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.amazonaws.com%2Fuploads%2Farticles%2F802xth2a5431oyz5m03d.png" alt="Screenshot of the HuntOS Kanban board"&gt;&lt;/a&gt;&lt;/p&gt;

&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.amazonaws.com%2Fuploads%2Farticles%2Fu9ujnm9unic56qsh76jh.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.amazonaws.com%2Fuploads%2Farticles%2Fu9ujnm9unic56qsh76jh.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;PS: I don't speak german but added that to my profile anyways.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance: How Good is the Agent?
&lt;/h2&gt;

&lt;p&gt;Since I didn't write the code, I have to judge the agent as if it were a junior developer I hired.&lt;/p&gt;

&lt;h3&gt;
  
  
  Code Quality
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Note: I am still looking into the best ways to quantitatively measure this. Some strategies I'm considering are running complexity analysis, looking at test coverage (which the agent also has to write!), and using automated linting tools to see how "clean" the output is. For now, the "vibe" is that it is surprisingly modular.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Project Quality
&lt;/h3&gt;

&lt;p&gt;The agent exceeded my expectations in several areas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Resume Generation:&lt;/strong&gt; It correctly identified my most relevant projects and experience, perfectly adhering to the Markdown templates I provided.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Job Discovery:&lt;/strong&gt; It successfully scraped positions based on my specific preferences like location, compensation, and role type.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Submission Rate:&lt;/strong&gt; I’ve achieved a &lt;strong&gt;65% successful submission rate&lt;/strong&gt; so far.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The "Rough Edges":&lt;/strong&gt; It’s not perfect. It still struggles with sites that require a login or have very strict form validation. Interestingly, using &lt;code&gt;Qwen 3.5 A30B&lt;/code&gt;, I noticed it would occasionally try to type "Two" into a field that expected an integer. Also, the screenshot logic isn't 100% accurate yet, so some logs are a bit fuzzy.&lt;br&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.amazonaws.com%2Fuploads%2Farticles%2Fmim0stqtmpxbjjguomf3.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.amazonaws.com%2Fuploads%2Farticles%2Fmim0stqtmpxbjjguomf3.png" alt="Screenshot of a humorous agent "&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  High Tech, Low Cost
&lt;/h2&gt;

&lt;p&gt;One of my main goals was to keep the project accessible. We use a "local-first" approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SQLite&lt;/strong&gt; for all data storage (no expensive cloud DBs).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Self-hostable models:&lt;/strong&gt; It supports Ollama and LMStudio, meaning you can run the "brains" of the operation on your own hardware.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smart Model Routing:&lt;/strong&gt; You can use cheaper models for simple tasks and save the "expensive" tokens for the complex reasoning.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Bill: What did this actually cost?
&lt;/h3&gt;

&lt;p&gt;To go from an empty folder to a fully functional, agent-driven OS, the financial investment was minimal:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Copilot Subscription:&lt;/strong&gt; $10 (The primary "engine" for the Zed agents).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LLM API Costs:&lt;/strong&gt; ~$0 (By using self-hostable models and free-tier/low-cost tokens).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manual Labor:&lt;/strong&gt; $0 (Zero lines of code written by hand).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Electricity:&lt;/strong&gt; TBD (My roommates haven't seen the bill yet, but my GPU fans were spinning so fast I’m pretty sure the living room hovered a few inches off the ground).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Seriously, the marginal impact on the electricity bill is probably the most expensive part of the stack, and even then, I'm splitting it three ways. Sorry guys.&lt;/p&gt;

&lt;h2&gt;
  
  
  The "Agentic" Shift
&lt;/h2&gt;

&lt;p&gt;Building HuntOS showed me just how strong AI agents have become. We are reaching a point where the barrier between an idea and a working prototype is thinner than ever.&lt;/p&gt;

&lt;p&gt;The shift in programming paradigms reminds me of how we moved from manual "stick shift" vehicles to automatic ones. In the past, you had to be intimately involved in every gear change—writing every line of code by hand. Now, we are moving toward an "automatic" experience where the AI handles the mechanics of the transmission. You still need to know how to drive, where you're going, and when to hit the brakes, but you aren't bogged down by the manual labor of the gearbox.&lt;/p&gt;

&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.amazonaws.com%2Fuploads%2Farticles%2F9hqrks4wkrvsw1etx2kl.jpg" 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.amazonaws.com%2Fuploads%2Farticles%2F9hqrks4wkrvsw1etx2kl.jpg" alt="Embrace vibe coding"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We still need a "driver" for now, but I can see a future where "Full Self-Driving" for software becomes a reality. In that world, the only real contribution from the human "driver" is to decide which destination actually generates the most value.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use HuntOS
&lt;/h2&gt;

&lt;p&gt;If you want to try this out yourself, here is the quick-start guide:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Install Bun:&lt;/strong&gt; Ensure you have the &lt;code&gt;bun&lt;/code&gt; runtime installed locally.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Install Chrome:&lt;/strong&gt; You’ll need &lt;code&gt;google-chrome-stable&lt;/code&gt; for the browser automation.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Start it up:&lt;/strong&gt; Run the &lt;code&gt;bun start&lt;/code&gt; script. You should see a Chrome instance launch.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Login:&lt;/strong&gt; In that specific Chrome instance, log in to your LinkedIn account.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Navigate:&lt;/strong&gt; Go to the HuntOS landing page in your local browser and follow the onboarding instructions.&lt;/li&gt;
&lt;/ol&gt;

&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.amazonaws.com%2Fuploads%2Farticles%2Fazgy24loan3hxa30mz98.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.amazonaws.com%2Fuploads%2Farticles%2Fazgy24loan3hxa30mz98.png" alt="Image of the HuntOS landing page/onboarding"&gt;&lt;/a&gt;&lt;br&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.amazonaws.com%2Fuploads%2Farticles%2Finsw92umjaqd601body0.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.amazonaws.com%2Fuploads%2Farticles%2Finsw92umjaqd601body0.png" alt="Screenshot of the Admin Panel"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The "Agentic" Shift
&lt;/h2&gt;

&lt;p&gt;However, this experience also taught me that &lt;strong&gt;software engineering isn't dead—it's evolving.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;While I didn't write the lines of code, I had to spend a lot of time thinking about infrastructure, data flow, and how to prompt the agents effectively. You still need to understand the "why" behind the code to debug issues and maintain a coherent architecture. You have to guide the "vibe" so the project doesn't turn into a spaghetti mess.&lt;/p&gt;
&lt;h2&gt;
  
  
  Open Sourcing the Dream
&lt;/h2&gt;

&lt;p&gt;I’m excited to announce that HuntOS is now open source. I invite individual contributors to help expand on the functionalities of the software and make into something practical that people can actually use. (Also I ran out of credits so....)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The License:&lt;/strong&gt; I’ve released this under a license that ensures it stays free for individuals. It should not be used for profit or by companies looking to charge for these tools. This is by the people, for the people.&lt;/p&gt;

&lt;p&gt;You can find the project here: &lt;br&gt;


&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Blakeinstein" rel="noopener noreferrer"&gt;
        Blakeinstein
      &lt;/a&gt; / &lt;a href="https://github.com/Blakeinstein/HuntOS" rel="noopener noreferrer"&gt;
        HuntOS
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Tool to auto apply to jobs
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/Blakeinstein/HuntOS/static/logo.svg"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FBlakeinstein%2FHuntOS%2Fstatic%2Flogo.svg" alt="HuntOS" width="160" height="160"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;HuntOS&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;
  &lt;strong&gt;Automated job application OS — powered by AI agents, browser automation, and a fully local stack.&lt;/strong&gt;
&lt;/p&gt;

&lt;p&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/23d30f031d248239e19fb40acc5591ed49a01422b44dd95bbc95520698653185/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f72756e74696d652d62756e2d6639663165313f6c6f676f3d62756e266c6f676f436f6c6f723d626c61636b"&gt;&lt;img src="https://camo.githubusercontent.com/23d30f031d248239e19fb40acc5591ed49a01422b44dd95bbc95520698653185/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f72756e74696d652d62756e2d6639663165313f6c6f676f3d62756e266c6f676f436f6c6f723d626c61636b" alt="bun"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/3e2e7df98a11da239d92c683133308e4443aa4e5c09391fbf4befe1814ebbb14/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6672616d65776f726b2d5376656c74654b69742d6666336530303f6c6f676f3d7376656c7465266c6f676f436f6c6f723d7768697465"&gt;&lt;img src="https://camo.githubusercontent.com/3e2e7df98a11da239d92c683133308e4443aa4e5c09391fbf4befe1814ebbb14/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6672616d65776f726b2d5376656c74654b69742d6666336530303f6c6f676f3d7376656c7465266c6f676f436f6c6f723d7768697465" alt="SvelteKit"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/754f66c178dd17b6f197e536353dbe78a1bcf0ecb70253f9711d86c6e33bbd84/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6167656e74732d4d61737472612d363336366631"&gt;&lt;img src="https://camo.githubusercontent.com/754f66c178dd17b6f197e536353dbe78a1bcf0ecb70253f9711d86c6e33bbd84/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6167656e74732d4d61737472612d363336366631" alt="Mastra"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/4062f75d069767f1835f6d91d5b5742b4a113c8f2c71d2cbb98b6ffa298996e7/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6175746f6d6174696f6e2d4344502d304541354539"&gt;&lt;img src="https://camo.githubusercontent.com/4062f75d069767f1835f6d91d5b5742b4a113c8f2c71d2cbb98b6ffa298996e7/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6175746f6d6174696f6e2d4344502d304541354539" alt="CDP"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/e3613f51e9255efbed5838a4245417734016687065ef5f6768fa0305307d26c3/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d47504c2d2d332e302d323263353565"&gt;&lt;img src="https://camo.githubusercontent.com/e3613f51e9255efbed5838a4245417734016687065ef5f6768fa0305307d26c3/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d47504c2d2d332e302d323263353565" alt="GPL-3.0"&gt;&lt;/a&gt;
&lt;/p&gt;




&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;What is HuntOS?&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;HuntOS is a local-first, agent-driven job application platform. It combines a SvelteKit UI, Mastra AI agents, and Chrome DevTools Protocol automation to research job listings, tailor resumes, and submit applications — while you focus on what matters.&lt;/p&gt;

&lt;p&gt;&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;br&gt;
&lt;thead&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;th&gt;Capability&lt;/th&gt;
&lt;br&gt;
&lt;th&gt;Details&lt;/th&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;/thead&gt;
&lt;br&gt;
&lt;tbody&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;&lt;strong&gt;Job board scraping&lt;/strong&gt;&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;LinkedIn, Greenhouse, and generic boards&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;&lt;strong&gt;Resume generation&lt;/strong&gt;&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;Agent-tailored Markdown + PDF per application&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;&lt;strong&gt;Browser automation&lt;/strong&gt;&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;Full CDP-driven form filling and submission&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;&lt;strong&gt;Kanban pipeline&lt;/strong&gt;&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;Track every application from research to offer&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;&lt;strong&gt;Audit trail&lt;/strong&gt;&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;Per-run annotated screenshots and action logs&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;&lt;strong&gt;Fully local&lt;/strong&gt;&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;SQLite databases, no cloud storage required&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;/tbody&gt;
&lt;br&gt;
&lt;/table&gt;&lt;/div&gt;&lt;br&gt;
&lt;/p&gt;


&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Usage Guide&lt;/h2&gt;
&lt;/div&gt;


&lt;ol&gt;

&lt;li&gt;

&lt;strong&gt;Install Bun:&lt;/strong&gt; Ensure you have the &lt;code&gt;bun&lt;/code&gt; runtime installed locally.&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Install Chrome:&lt;/strong&gt; You’ll need &lt;code&gt;google-chrome-stable&lt;/code&gt; for the browser automation.&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Start it up:&lt;/strong&gt; Run the &lt;code&gt;bun start&lt;/code&gt; script. You should see a Chrome instance launch.&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Login:&lt;/strong&gt; In that specific Chrome instance…&lt;/li&gt;

&lt;/ol&gt;
&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Blakeinstein/HuntOS" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;





&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;We live in a world where AI can take jobs, but it can also give us the tools to find new ones faster than ever. HuntOS started as a way to help a friend and understand the market, but it turned into a lesson in the power of modern development.&lt;/p&gt;

&lt;p&gt;Whether you're a seasoned engineer or someone with just an idea, the tools are there. All you need is a few dollars and the right prompts.&lt;/p&gt;

&lt;p&gt;Happy hunting!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>automation</category>
      <category>vibecoding</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Using the new Native Dialog API as a reusable component in Vue 3</title>
      <dc:creator>Blaine</dc:creator>
      <pubDate>Thu, 15 Jun 2023 01:51:58 +0000</pubDate>
      <link>https://dev.to/blainesensei/using-the-new-native-dialog-api-as-a-reusable-component-in-vue-3-4aoc</link>
      <guid>https://dev.to/blainesensei/using-the-new-native-dialog-api-as-a-reusable-component-in-vue-3-4aoc</guid>
      <description>&lt;h2&gt;
  
  
  📝 The Native HTML Dialog
&lt;/h2&gt;

&lt;p&gt;We've all heard the buzz around browser native dialogs which are now widely supported across all modern browsers. Now you no longer need to depend on third party packages to achieve a user friendly dialog/popover experience.&lt;/p&gt;

&lt;p&gt;Now if you are just here for the code, here it is below. However, if you are here to understand how we got here, stick to the end!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dialog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HTMLDialogElement&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;defineProps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;classes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;visible&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;showModal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;dialog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;showModal&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;visible&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nf"&gt;defineExpose&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;show&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;showModal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;close&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;returnVal&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;dialog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;returnVal&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nx"&gt;visible&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;dialog&lt;/span&gt;
    &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;"dialog"&lt;/span&gt;
    &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;close=&lt;/span&gt;&lt;span class="s"&gt;"visible = false"&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt;
      &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"visible"&lt;/span&gt;
      &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;"dialog"&lt;/span&gt;
      &lt;span class="na"&gt;:class=&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;{
        [props.classes]: props.classes,
      }"
    &amp;gt;
      &lt;span class="nt"&gt;&amp;lt;slot&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/dialog&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  👷 The Breakdown
&lt;/h2&gt;

&lt;p&gt;The new Dialog API is pretty straightforward. As seen from the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog" rel="noopener noreferrer"&gt;MDN Page&lt;/a&gt;, all you need to get started is a simple &lt;code&gt;&amp;lt;dialog&amp;gt;&lt;/code&gt; element. Any reference to this element will have programatic access to the function &lt;code&gt;.showModal()&lt;/code&gt; to toggle the dialog, so you could do this with a button!.&lt;/p&gt;

&lt;h3&gt;
  
  
  Vanilla HTML
&lt;/h3&gt;

&lt;p&gt;Lets take a look at the provided example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dialog&lt;/span&gt; &lt;span class="na"&gt;open&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Greetings, one and all!&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;"dialog"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&amp;gt;&lt;/span&gt;OK&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dialog&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do note the additional comment on MDN,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Because this dialog was opened via the open attribute, it is non-modal. In this example, when the dialog is dismissed, no method is provided to re-open it. Opening dialogs via HTMLDialogElement.show() is preferred over the toggling of the boolean open attribute.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So although this is a good demonstration of the result, programatic access is suggested.&lt;/p&gt;

&lt;p&gt;Looking closer, other than the open attribute, we have&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A form component, with &lt;code&gt;method="dialog"&lt;/code&gt;. This is a new form method, which on form submission, automatically closes the dialog with a submit event.&lt;/li&gt;
&lt;li&gt;Accessibility, pressing tab will toggle only through the form elements in the dialog.&lt;/li&gt;
&lt;li&gt;The dialog content will be shown in a new layer, which can be visualized from the browsers dev tools.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  🤖 Difference between show and showModal
&lt;/h3&gt;

&lt;p&gt;There are two ways to open the dialog.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;.show()&lt;/code&gt; will toggle open the dialog, but

&lt;ul&gt;
&lt;li&gt;Esc will not close the element.&lt;/li&gt;
&lt;li&gt;Backdrop will not be darkened (default styling).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.showModal()&lt;/code&gt; will toggle open the dialog in the modal mode,

&lt;ul&gt;
&lt;li&gt;Esc will close the modal&lt;/li&gt;
&lt;li&gt;Backdrop will be darkened in default styling. (The styling can be changed).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  ⛵️ Bringing in Vue
&lt;/h3&gt;

&lt;p&gt;Lets be real, you are probably not working on a project with vanilla HTML, it is nice but does not scale. You might be using a Frontend library, probably something among React, Vue or Svelte. I will be covering Vue here, but the design pattern should be similar in Svelte. Pretty sure, React folk don't have to worry about not using Third Party packages :P.&lt;/p&gt;

&lt;p&gt;A simple solution in Vue is to just slap a &lt;code&gt;&amp;lt;slot /&amp;gt;&lt;/code&gt;, have a two way binding to the &lt;code&gt;open&lt;/code&gt; attribute via props and call it a day. Lets look at this example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;defineProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="na"&gt;open&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;dialog&lt;/span&gt; &lt;span class="na"&gt;:open=&lt;/span&gt;&lt;span class="s"&gt;"props.open"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;"dialog"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;slot&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dialog&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a good enough solution but lets see if we can do better! &lt;/p&gt;

&lt;h3&gt;
  
  
  💪 Trying to do better
&lt;/h3&gt;

&lt;p&gt;We will try to&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Adhere to using programmatic access.&lt;/li&gt;
&lt;li&gt;See if we can mount the child component only when the modal is open, so that any mount hooks run only when needed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To achieve the first we shall use a &lt;code&gt;ref&lt;/code&gt;. This way we get a ref to the dialog element, to be able to call the &lt;code&gt;showModal&lt;/code&gt; function. We avoid ids, because we want this re-usable! Plus avoid &lt;code&gt;document.querySelector&lt;/code&gt; makes it SSR safe?. Don't quote me on that.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dialog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HTMLDialogElement&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;....&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;dialog&lt;/span&gt;
    &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;"dialog"&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
   ...
&lt;span class="nt"&gt;&amp;lt;/dialog&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We then declare a function to call showModal(), then expose that function to parent components via &lt;code&gt;defineExpose()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;showModal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;dialog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;showModal&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nf"&gt;defineExpose&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;show&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;showModal&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The parent component can then bind a ref to the modal and toggle dialog as needed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Modal&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;path/to/Modal.vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;modal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;InstanceType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;Modal&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;showModal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;modal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With that complete lets also get conditional loading so that mount hooks work proper (otherwise this is equivalent to a &lt;code&gt;v-show&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;We create a state called visible and toggle that when state of dialog changes. We shall set visible to true, when we show the modal, and use the close event to toggle it to false.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;visible&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;showModal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;dialog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;showModal&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;visible&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;dialog&lt;/span&gt;
    &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;"dialog"&lt;/span&gt;
    &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;close=&lt;/span&gt;&lt;span class="s"&gt;"visible = false"&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt;
      &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"visible"&lt;/span&gt;
      &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;"dialog"&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;slot&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/dialog&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and there's that! Note that if you still want a cleaner approach, you can still use the &lt;code&gt;open&lt;/code&gt; prop for conditional rendering as well as the &lt;code&gt;open&lt;/code&gt; attribute but do note that some of the accessibility will be lost.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;defineProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="na"&gt;open&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;dialog&lt;/span&gt; &lt;span class="na"&gt;:open=&lt;/span&gt;&lt;span class="s"&gt;"props.open"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"props.open"&lt;/span&gt; &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;"dialog"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;slot&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dialog&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the final result is the code at the very start of the guide! &lt;/p&gt;

&lt;h3&gt;
  
  
  🎨 With DaisyUI and TailwindCSS!
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://daisyui.com/docs/changelog/#new-features-on-components" rel="noopener noreferrer"&gt;DaisyUI v3&lt;/a&gt; supports native modals! Here is a quick custom component with slots and styles to make life easier for you!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dialog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HTMLDialogElement&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;defineProps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;confirmText&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Confirm&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;cancelText&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Cancel&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;hideConfirm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;showCancel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;classes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;emit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;defineEmits&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;confirm&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cancel&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cancel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;dialog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cancel&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;confirm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;dialog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;confirm&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;visible&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;showModal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;dialog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;showModal&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;visible&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nf"&gt;defineExpose&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;show&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;showModal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;close&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;returnVal&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;dialog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;returnVal&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nx"&gt;visible&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;dialog&lt;/span&gt;
    &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;"dialog"&lt;/span&gt;
    &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"modal modal-bottom sm:modal-middle"&lt;/span&gt;
    &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;close=&lt;/span&gt;&lt;span class="s"&gt;"visible = false"&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt;
      &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"visible"&lt;/span&gt;
      &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;"dialog"&lt;/span&gt;
      &lt;span class="na"&gt;:class=&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;{
        'modal-box rounded-none p-4': true,
        [props.classes]: props.classes,
      }"
    &amp;gt;
      &lt;span class="nt"&gt;&amp;lt;slot&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"modal-action"&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"!props.hideConfirm || props.showCancel"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;slot&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"footer"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;slot&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"actionButtons"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt;
            &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"props.showCancel"&lt;/span&gt;
            &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt;
            &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn"&lt;/span&gt;
            &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click.prevent=&lt;/span&gt;&lt;span class="s"&gt;"cancel"&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cancelText&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt;
            &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"!props.hideConfirm"&lt;/span&gt;
            &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;
            &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn btn-primary"&lt;/span&gt;
            &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click.prevent=&lt;/span&gt;&lt;span class="s"&gt;"confirm"&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;confirmText&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/slot&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;"dialog"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"modal-backdrop"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;button&amp;gt;&lt;/span&gt;close&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/dialog&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is a stackblitz for the same&lt;br&gt;
&lt;iframe src="https://stackblitz.com/edit/vitejs-vite-uwpxdn?file=src%2Fcomponents%2FModal.vue" width="100%" height="500"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;Thanks so much for reading! If you have any improvements on the above do share in the comments. As for me, I really love the new native dialog, and the future things coming to vanilla HTML, like the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/popover" rel="noopener noreferrer"&gt;Popover element&lt;/a&gt; bring simpler tooltips and &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/ViewTransition" rel="noopener noreferrer"&gt;page transitions&lt;/a&gt; which may enable frameworks like astro to simplify page transitions via CSS where JS libraries like SWUP which takeover client side page navigation are the only way to transition.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>vue</category>
      <category>html</category>
      <category>typescript</category>
    </item>
  </channel>
</rss>
