<?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: Mike Buyco</title>
    <description>The latest articles on DEV Community by Mike Buyco (@mbuyco).</description>
    <link>https://dev.to/mbuyco</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%2F352108%2F8735f078-1482-4977-affd-06f86a99225f.png</url>
      <title>DEV Community: Mike Buyco</title>
      <link>https://dev.to/mbuyco</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mbuyco"/>
    <language>en</language>
    <item>
      <title>Retrofitting OpenSpec Into Existing Projects: A Practical Playbook</title>
      <dc:creator>Mike Buyco</dc:creator>
      <pubDate>Wed, 08 Jul 2026 03:35:57 +0000</pubDate>
      <link>https://dev.to/mbuyco/retrofitting-openspec-into-existing-projects-a-practical-playbook-5g0m</link>
      <guid>https://dev.to/mbuyco/retrofitting-openspec-into-existing-projects-a-practical-playbook-5g0m</guid>
      <description>&lt;p&gt;Most teams don't have the luxury of starting from a clean slate. They have production systems, active customers, shipping deadlines, and years of accumulated decisions. That's exactly where OpenSpec delivers the most value.&lt;/p&gt;

&lt;p&gt;The objective isn't to stop development and rewrite documentation. It's to capture reality, improve visibility, and make the existing system easier for both engineers and AI to understand.&lt;/p&gt;

&lt;p&gt;The fastest path to ROI is incremental adoption alongside normal development.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install and Initialize
&lt;/h2&gt;

&lt;p&gt;Start from your project root:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install globally&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @fission-ai/openspec@latest

&lt;span class="c"&gt;# Verify&lt;/span&gt;
openspec &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then initialize in your existing repo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;your-existing-project
openspec init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is interactive. OpenSpec will prompt you to select which AI tools to configure (Claude Code, Cursor, Windsurf, Codex, Copilot, etc.). You can skip this non-interactively:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Configure for specific tools&lt;/span&gt;
openspec init &lt;span class="nt"&gt;--tools&lt;/span&gt; claude,cursor

&lt;span class="c"&gt;# Or skip tool config entirely&lt;/span&gt;
openspec init &lt;span class="nt"&gt;--tools&lt;/span&gt; none
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What gets created:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;your-project/
├── openspec/
│   ├── config.yaml         # Project configuration
│   ├── specs/              # Your specifications (source of truth)
│   └── changes/            # Proposed changes
├── .claude/skills/         # (if Claude selected)
├── .cursor/commands/       # (if Cursor selected)
└── CLAUDE.md               # (if Claude selected)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Commit this to version control. Your specs belong alongside the code they describe.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start With an Architecture Audit
&lt;/h2&gt;

&lt;p&gt;Don't begin by writing specifications. Begin by understanding what already exists.&lt;/p&gt;

&lt;p&gt;Use &lt;code&gt;/opsx:explore&lt;/code&gt; in your AI assistant to read the area you're about to touch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You: /opsx:explore

AI:  What would you like to explore?

You: I need to understand how our payment processing works — what services
     are involved, what the failure modes are, and where rate limits hit.

AI:  Let me trace it... [reads the codebase]
     Payment flow: CheckoutController → PaymentService → StripeAdapter
     → PaymentConfirmedEvent → InvoiceService.
     Failure modes: Stripe timeout (no retry), webhook idempotency not enforced.
     No rate limiting layer exists today.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This saves the most pain on large codebases. The AI maps your actual structure before any specs are written.&lt;/p&gt;

&lt;p&gt;Inventory the major parts of the application:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Business domains&lt;/li&gt;
&lt;li&gt;APIs&lt;/li&gt;
&lt;li&gt;Database models&lt;/li&gt;
&lt;li&gt;Background jobs&lt;/li&gt;
&lt;li&gt;Events&lt;/li&gt;
&lt;li&gt;External integrations&lt;/li&gt;
&lt;li&gt;Authentication&lt;/li&gt;
&lt;li&gt;Authorization&lt;/li&gt;
&lt;li&gt;Infrastructure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For each business capability, answer practical questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What problem does it solve?&lt;/li&gt;
&lt;li&gt;Where does the code live?&lt;/li&gt;
&lt;li&gt;What triggers it?&lt;/li&gt;
&lt;li&gt;What data comes in?&lt;/li&gt;
&lt;li&gt;What data goes out?&lt;/li&gt;
&lt;li&gt;Which systems depend on it?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ignore implementation details. Focus on system boundaries.&lt;/p&gt;

&lt;h2&gt;
  
  
  Organize Around Business Domains
&lt;/h2&gt;

&lt;p&gt;Many mature codebases are organized by technical layers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app/
├── controllers/
├── models/
├── services/
└── helpers/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Those folders don't describe the business.&lt;/p&gt;

&lt;p&gt;Instead, identify stable business capabilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Orders&lt;/li&gt;
&lt;li&gt;Billing&lt;/li&gt;
&lt;li&gt;Inventory&lt;/li&gt;
&lt;li&gt;Customers&lt;/li&gt;
&lt;li&gt;Notifications&lt;/li&gt;
&lt;li&gt;Reporting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each capability becomes an OpenSpec domain under &lt;code&gt;openspec/specs/&lt;/code&gt;. You don't design the whole taxonomy up front — create a domain folder when your first change in that area needs one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# After your first change is archived, specs accumulate naturally:&lt;/span&gt;
openspec list &lt;span class="nt"&gt;--specs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This structure remains stable even as implementation evolves.&lt;/p&gt;

&lt;h2&gt;
  
  
  Document the System as It Exists — One Change at a Time
&lt;/h2&gt;

&lt;p&gt;Resist the urge to back-fill everything. Writing specs for code you aren't changing feels productive and usually isn't. Those specs go stale because nothing forces them to track reality.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The key insight: you write specs only for what you're about to change.&lt;/strong&gt; Your first change documents the slice it touches, the next change documents its slice, and over months your specs fill in naturally around the work you actually do.&lt;/p&gt;

&lt;p&gt;Here's how a real first change works:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You: /opsx:propose add-api-rate-limiting
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;OpenSpec creates the change directory with planning artifacts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openspec/changes/add-api-rate-limiting/
├── .openspec.yaml          # Change metadata
├── proposal.md             # What and why
├── specs/                  # Delta specs (what changes)
├── design.md               # Technical approach
└── tasks.md                # Implementation steps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then implement and archive:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You: /opsx:apply

AI: [implements the rate limiting]

You: /opsx:archive
AI:  Archiving add-api-rate-limiting...
     ✓ Merged specs into openspec/specs/api/rate-limiting/spec.md
     ✓ Moved to openspec/changes/archive/2026-07-08-add-api-rate-limiting/
     Done. Ready for the next change.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your &lt;code&gt;openspec/specs/&lt;/code&gt; directory doesn't start full and complete. It starts nearly empty and accumulates. Each archived change merges its delta in. The spec becomes thorough only after you've made several changes in that area — which is exactly when you want it thorough.&lt;/p&gt;

&lt;p&gt;If placing an order currently reserves inventory, captures payment, generates an invoice, and sends an email, document exactly that sequence. Future improvements belong in future specifications. Accuracy is more valuable than aspiration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Turn Existing APIs Into Specifications
&lt;/h2&gt;

&lt;p&gt;Every API endpoint already defines a contract. Extract that contract into a structured specification.&lt;/p&gt;

&lt;p&gt;Start a change that captures one endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You: /opsx:propose document-checkout-api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the delta spec, capture:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Endpoint&lt;/li&gt;
&lt;li&gt;Inputs&lt;/li&gt;
&lt;li&gt;Validation rules&lt;/li&gt;
&lt;li&gt;Business behavior&lt;/li&gt;
&lt;li&gt;Responses&lt;/li&gt;
&lt;li&gt;Error conditions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The implementation already contains this information. The goal is simply to make it explicit and discoverable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Surface Business Rules
&lt;/h2&gt;

&lt;p&gt;Business rules are often scattered throughout the codebase: service classes, validation logic, authorization policies, helper methods, database triggers.&lt;/p&gt;

&lt;p&gt;Collect them into a single source of truth using the delta spec format. Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Orders above a certain value require approval.&lt;/li&gt;
&lt;li&gt;Administrators may bypass approval.&lt;/li&gt;
&lt;li&gt;Refunds are only allowed before settlement.&lt;/li&gt;
&lt;li&gt;Inactive users cannot create new orders.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These rules define how the business operates. They deserve to be documented independently of implementation.&lt;/p&gt;

&lt;p&gt;When you archive the change, the rules merge into the domain spec and stay there.&lt;/p&gt;

&lt;h2&gt;
  
  
  Map the Domain Model
&lt;/h2&gt;

&lt;p&gt;Specifications should describe the business entities that matter. For each entity, capture:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fields&lt;/li&gt;
&lt;li&gt;Relationships&lt;/li&gt;
&lt;li&gt;Lifecycle&lt;/li&gt;
&lt;li&gt;Immutable attributes&lt;/li&gt;
&lt;li&gt;Derived values&lt;/li&gt;
&lt;li&gt;Calculated fields&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This creates a shared understanding of the data model without requiring engineers to reverse-engineer the database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Capture Workflows and Events
&lt;/h2&gt;

&lt;p&gt;Modern systems are driven by workflows and events. Document the flow from one business event to the next.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Order created&lt;/li&gt;
&lt;li&gt;Inventory reserved&lt;/li&gt;
&lt;li&gt;Payment requested&lt;/li&gt;
&lt;li&gt;Payment confirmed&lt;/li&gt;
&lt;li&gt;Invoice generated&lt;/li&gt;
&lt;li&gt;Customer notified&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These workflows often span multiple services and repositories. Making them explicit improves onboarding, debugging, and future refactoring.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inventory External Dependencies
&lt;/h2&gt;

&lt;p&gt;Every production system relies on external services. Document each dependency along with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Purpose&lt;/li&gt;
&lt;li&gt;Authentication method&lt;/li&gt;
&lt;li&gt;Retry strategy&lt;/li&gt;
&lt;li&gt;Failure behavior&lt;/li&gt;
&lt;li&gt;Rate limits&lt;/li&gt;
&lt;li&gt;Fallback process&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This information becomes invaluable during incidents and reduces operational risk as the system grows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prioritize High-Value Domains
&lt;/h2&gt;

&lt;p&gt;Don't attempt to specify the entire platform in one sprint. Start with the areas that carry the greatest business value.&lt;/p&gt;

&lt;p&gt;A typical priority order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Authentication&lt;/li&gt;
&lt;li&gt;Payments&lt;/li&gt;
&lt;li&gt;Orders&lt;/li&gt;
&lt;li&gt;Billing&lt;/li&gt;
&lt;li&gt;Notifications&lt;/li&gt;
&lt;li&gt;Reporting&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Early wins build momentum while delivering immediate operational benefits.&lt;/p&gt;

&lt;h2&gt;
  
  
  Validate Before You Ship
&lt;/h2&gt;

&lt;p&gt;OpenSpec validates your changes and specs for structural issues. Use this before every archive:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Validate a specific change&lt;/span&gt;
openspec validate add-api-rate-limiting

&lt;span class="c"&gt;# Validate everything — useful before CI or a release&lt;/span&gt;
openspec validate &lt;span class="nt"&gt;--all&lt;/span&gt; &lt;span class="nt"&gt;--strict&lt;/span&gt;

&lt;span class="c"&gt;# JSON output for scripts&lt;/span&gt;
openspec validate &lt;span class="nt"&gt;--all&lt;/span&gt; &lt;span class="nt"&gt;--json&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Validating add-api-rate-limiting...
  ✓ proposal.md valid
  ✓ specs/api/spec.md valid
  ✓ design.md valid
  ✓ tasks.md valid

0 warnings, 0 errors
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Validation catches structural problems before the AI writes code or before you merge. Make it a habit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check Health Across References
&lt;/h2&gt;

&lt;p&gt;If your project references external stores (standalone OpenSpec repos), use &lt;code&gt;doctor&lt;/code&gt; to verify everything is connected:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Root health:          ✓ healthy
Store "team-context": ✓ registered, remote matches origin
References:           ✓ 1/1 resolved
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When a store isn't available locally, &lt;code&gt;doctor&lt;/code&gt; tells you exactly how to fix it — typically a &lt;code&gt;git clone&lt;/code&gt; and &lt;code&gt;openspec store register&lt;/code&gt; command.&lt;/p&gt;

&lt;h2&gt;
  
  
  Track Progress With Status
&lt;/h2&gt;

&lt;p&gt;Check where a change stands in the artifact pipeline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Interactive selection&lt;/span&gt;
openspec status

&lt;span class="c"&gt;# Specific change&lt;/span&gt;
openspec status &lt;span class="nt"&gt;--change&lt;/span&gt; add-api-rate-limiting

&lt;span class="c"&gt;# JSON for agent use&lt;/span&gt;
openspec status &lt;span class="nt"&gt;--change&lt;/span&gt; add-api-rate-limiting &lt;span class="nt"&gt;--json&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Change: add-api-rate-limiting
Schema: spec-driven
Progress: 3/4 artifacts complete

[x] proposal
[x] specs
[ ] design
[-] tasks (blocked by: design)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is especially useful mid-sprint when you have multiple changes in flight.&lt;/p&gt;

&lt;h2&gt;
  
  
  Browse What Exists
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# List active changes&lt;/span&gt;
openspec list

&lt;span class="c"&gt;# List specs by domain&lt;/span&gt;
openspec list &lt;span class="nt"&gt;--specs&lt;/span&gt;

&lt;span class="c"&gt;# Interactive dashboard&lt;/span&gt;
openspec view

&lt;span class="c"&gt;# Show a specific change or spec&lt;/span&gt;
openspec show add-api-rate-limiting
openspec show auth &lt;span class="nt"&gt;--type&lt;/span&gt; spec
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Keep Specifications Close to the Code
&lt;/h2&gt;

&lt;p&gt;Specifications should live alongside the implementation they describe. Keeping documentation within each domain makes updates part of normal development instead of a separate maintenance task.&lt;/p&gt;

&lt;p&gt;When specifications travel with the code, they're far more likely to remain accurate over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make Specifications Part of Every Pull Request
&lt;/h2&gt;

&lt;p&gt;Specifications shouldn't be written once and forgotten. Instead, make them part of the development workflow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Update the specification (via &lt;code&gt;/opsx:propose&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Implement the change (via &lt;code&gt;/opsx:apply&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Run validation (&lt;code&gt;openspec validate&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Review both specification and code together.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Treating specifications as part of the definition of done keeps documentation synchronized with production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generate Better Tests
&lt;/h2&gt;

&lt;p&gt;Every documented workflow naturally becomes a set of test cases. A simple "Cancel Order" workflow expands into scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Customer cancels their own order&lt;/li&gt;
&lt;li&gt;Administrator cancels an order&lt;/li&gt;
&lt;li&gt;Order already shipped&lt;/li&gt;
&lt;li&gt;Order already cancelled&lt;/li&gt;
&lt;li&gt;Payment pending&lt;/li&gt;
&lt;li&gt;Refund already processed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using specifications to drive testing increases coverage while ensuring tests reflect business behavior rather than implementation details.&lt;/p&gt;

&lt;h2&gt;
  
  
  Give AI Context Instead of Source Code
&lt;/h2&gt;

&lt;p&gt;Large codebases overwhelm both people and AI. Instead of exposing hundreds of thousands of lines of implementation, provide structured specifications for the relevant domains.&lt;/p&gt;

&lt;p&gt;AI gains access to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Business terminology&lt;/li&gt;
&lt;li&gt;System boundaries&lt;/li&gt;
&lt;li&gt;Workflows&lt;/li&gt;
&lt;li&gt;Constraints&lt;/li&gt;
&lt;li&gt;Business rules&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result is more accurate code generation, better architectural suggestions, and fewer hallucinations caused by missing context.&lt;/p&gt;

&lt;p&gt;After archiving changes, &lt;code&gt;openspec instructions&lt;/code&gt; surfaces the relevant spec index to your AI assistant, so it can reference existing behavior when proposing new changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Update After CLI Upgrades
&lt;/h2&gt;

&lt;p&gt;When you upgrade the OpenSpec CLI, regenerate your project's instruction files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm update @fission-ai/openspec
openspec update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This re-generates tool configurations using your current profile and workflows. Skip this step and your AI assistant's slash commands may drift out of sync with the CLI version.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adopt Incrementally
&lt;/h2&gt;

&lt;p&gt;Successful OpenSpec adoption doesn't require a migration project. Instead, improve the specification whenever a feature is touched.&lt;/p&gt;

&lt;p&gt;The workflow becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/opsx:explore       # understand the area
/opsx:propose       # create the change
/opsx:apply         # implement
openspec validate   # verify structure
/opsx:archive       # merge into living specs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Over time, undocumented legacy systems become well-defined, verifiable, and significantly easier to evolve — without interrupting product delivery.&lt;/p&gt;

&lt;h2&gt;
  
  
  Immediate ROI
&lt;/h2&gt;

&lt;p&gt;Teams typically see value long before the migration is complete. Within the first few weeks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A shared architectural map&lt;/li&gt;
&lt;li&gt;Searchable business rules&lt;/li&gt;
&lt;li&gt;Clear API contracts&lt;/li&gt;
&lt;li&gt;Documented workflows&lt;/li&gt;
&lt;li&gt;Improved onboarding&lt;/li&gt;
&lt;li&gt;Better AI-assisted development&lt;/li&gt;
&lt;li&gt;More reliable regression testing&lt;/li&gt;
&lt;li&gt;Faster incident response through documented dependencies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each improvement compounds as more of the system becomes specified.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Pitfalls
&lt;/h2&gt;

&lt;p&gt;The most common mistakes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Documenting the desired architecture instead of production behavior.&lt;/strong&gt; Specs describe what ships today, not what you plan to build.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Attempting to specify the entire platform before shipping.&lt;/strong&gt; Let real changes drive your specs. One change at a time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Organizing specifications around technical layers instead of business domains.&lt;/strong&gt; Specs under &lt;code&gt;auth/&lt;/code&gt;, &lt;code&gt;payments/&lt;/code&gt;, &lt;code&gt;orders/&lt;/code&gt; stay meaningful. Specs under &lt;code&gt;controllers/&lt;/code&gt;, &lt;code&gt;models/&lt;/code&gt; mirror code structure, not business structure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Storing documentation in a separate repository.&lt;/strong&gt; Specs belong alongside the code they describe. Commit &lt;code&gt;openspec/&lt;/code&gt; to git.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Refactoring implementation before accurately documenting existing behavior.&lt;/strong&gt; Document first, then refactor. Otherwise you're specifying aspirational behavior that doesn't match production.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A 30-Day Rollout Plan
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Week 1:&lt;/strong&gt; Install OpenSpec, run &lt;code&gt;openspec init&lt;/code&gt;, audit the system, identify business domains, and inventory dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;openspec init
openspec doctor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Week 2:&lt;/strong&gt; Use &lt;code&gt;/opsx:explore&lt;/code&gt; and &lt;code&gt;/opsx:propose&lt;/code&gt; to fully specify the highest-value domain, including APIs, models, workflows, and business rules. Validate and archive each change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Week 3:&lt;/strong&gt; Make specification updates part of every pull request and code review. Use &lt;code&gt;openspec validate --all --strict&lt;/code&gt; in CI.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Week 4:&lt;/strong&gt; Expand into adjacent domains while generating tests from the documented workflows.&lt;/p&gt;

&lt;p&gt;By the end of the month, the team has a living specification, better onboarding materials, stronger regression coverage, and AI-ready documentation — all achieved without pausing product development.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ship the System You Have
&lt;/h2&gt;

&lt;p&gt;Retrofitting OpenSpec isn't about replacing your architecture. It's about making your current architecture understandable, verifiable, and easier to evolve.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;openspec init           &lt;span class="c"&gt;# start&lt;/span&gt;
/opsx:propose           &lt;span class="c"&gt;# one change at a time&lt;/span&gt;
openspec validate       &lt;span class="c"&gt;# verify before you ship&lt;/span&gt;
/opsx:archive           &lt;span class="c"&gt;# accumulate living specs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result isn't just better documentation. It's a development workflow where architecture, implementation, testing, and AI assistance all operate from the same source of truth.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>specdrivendevelopment</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Using Claude Code with OpenRouter via `claude-code-router` on Linux</title>
      <dc:creator>Mike Buyco</dc:creator>
      <pubDate>Mon, 29 Jun 2026 08:13:52 +0000</pubDate>
      <link>https://dev.to/mbuyco/using-claude-code-with-openrouter-via-claude-code-router-on-linux-1f8p</link>
      <guid>https://dev.to/mbuyco/using-claude-code-with-openrouter-via-claude-code-router-on-linux-1f8p</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Claude Code is Anthropic's powerful command-line coding assistant that brings AI directly into your terminal, while OpenRouter is an API aggregator that provides access to multiple AI models through a unified interface. The &lt;code&gt;claude-code-router&lt;/code&gt; package bridges these two tools, allowing you to route Claude Code requests through OpenRouter instead of Anthropic's direct API.&lt;/p&gt;

&lt;p&gt;This guide covers installation and configuration on Linux systems only.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before beginning, ensure your system meets these requirements:&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;OS&lt;/strong&gt;: Any modern Linux distribution (Ubuntu 20.04+, Debian 11+, Fedora 36+, Arch Linux, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Node.js&lt;/strong&gt;: Version 18.0.0 or higher&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;npm&lt;/strong&gt;: Version 8.0.0 or higher&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Git&lt;/strong&gt;: For cloning repositories if needed&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Verify Your Setup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check Node.js version&lt;/span&gt;
node &lt;span class="nt"&gt;--version&lt;/span&gt;

&lt;span class="c"&gt;# Check npm version&lt;/span&gt;
npm &lt;span class="nt"&gt;--version&lt;/span&gt;

&lt;span class="c"&gt;# Check Git version&lt;/span&gt;
git &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If Node.js is not installed or outdated, install it using your distribution's package manager or NodeSource:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Ubuntu/Debian - Using NodeSource&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://deb.nodesource.com/setup_20.x | &lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; bash -
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; nodejs

&lt;span class="c"&gt;# Fedora&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;dnf &lt;span class="nb"&gt;install &lt;/span&gt;nodejs npm

&lt;span class="c"&gt;# Arch Linux&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;pacman &lt;span class="nt"&gt;-S&lt;/span&gt; nodejs npm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Obtaining an OpenRouter API Key
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to &lt;a href="https://openrouter.ai" rel="noopener noreferrer"&gt;openrouter.ai&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Create an account or sign in&lt;/li&gt;
&lt;li&gt;Go to &lt;strong&gt;Keys&lt;/strong&gt; in your account dashboard&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create Key&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Copy the generated API key and store it securely&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Installing &lt;code&gt;claude-code-router&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;claude-code-router&lt;/code&gt; package should be installed globally alongside Anthropic's official CLI tool.&lt;br&gt;
&lt;/p&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; claude-code-router @anthropic-ai/claude-code
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configuration
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Method 1: Environment Variables
&lt;/h3&gt;

&lt;p&gt;Create or edit your shell configuration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# For Bash&lt;/span&gt;
nano ~/.bashrc

&lt;span class="c"&gt;# For Zsh&lt;/span&gt;
nano ~/.zshrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the following lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Claude Code Router Configuration&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;OPENROUTER_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"your-openrouter-api-key-here"&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;CLAUDE_CODE_ROUTER_MODEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"anthropic/claude-3.7-sonnet"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply the changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# For Bash&lt;/span&gt;
&lt;span class="nb"&gt;source&lt;/span&gt; ~/.bashrc

&lt;span class="c"&gt;# For Zsh&lt;/span&gt;
&lt;span class="nb"&gt;source&lt;/span&gt; ~/.zshrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Method 2: Configuration File
&lt;/h3&gt;

&lt;p&gt;Alternatively, create a configuration file in your home directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; ~/.claude-code-router
nano ~/.claude-code-router/config.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add your configuration (updated with the correct Claude 3.7 model string):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"apiKey"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"your-openrouter-api-key-here"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"anthropic/claude-3.7-sonnet"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"baseUrl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://openrouter.ai/api/v1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"maxTokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8192&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"temperature"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Secure Your API Key
&lt;/h3&gt;

&lt;p&gt;If you prefer using an environment file over a JSON config, ensure you lock down the file permissions so other users on the Linux system cannot read your API key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create a secure environment file&lt;/span&gt;
&lt;span class="nb"&gt;touch&lt;/span&gt; ~/.claude-code-router/.env
&lt;span class="nb"&gt;chmod &lt;/span&gt;600 ~/.claude-code-router/.env
nano ~/.claude-code-router/.env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the key inside the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OPENROUTER_API_KEY=sk-or-v1-your-actual-key-here
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Token Cost Optimization &amp;amp; Prompt Caching
&lt;/h2&gt;

&lt;p&gt;One of the primary benefits of routing Claude Code through OpenRouter is natively leveraging &lt;strong&gt;Prompt Caching&lt;/strong&gt; to heavily optimize your API costs.&lt;/p&gt;

&lt;p&gt;When working in large codebases, Claude Code sends significant contextual data (file structures, previous messages, and active file contents) with every single request. OpenRouter automatically supports Anthropic's prompt caching functionality:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Initial Requests:&lt;/strong&gt; Standard input token pricing applies as the context is written to the cache.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Subsequent Requests:&lt;/strong&gt; As long as your prompt prefix remains identical (within the 5-minute cache TTL), you receive up to a &lt;strong&gt;90% discount&lt;/strong&gt; on cached input tokens.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No extra configuration is required in &lt;code&gt;claude-code-router&lt;/code&gt; to enable this feature—OpenRouter handles the upstream caching headers automatically when translating requests to Anthropic's backend.&lt;/p&gt;

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

&lt;p&gt;Configure Claude Code to point to the local proxy, then initialize the router:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;ANTHROPIC_BASE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:8080"&lt;/span&gt;
ccr code
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configure LLM Models
&lt;/h2&gt;

&lt;p&gt;If you want to quickly switch models without editing config files manually:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note: This command redirects to a local web UI to configure your preferred OpenRouter models.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Check &lt;a href="https://openrouter.ai/models" rel="noopener noreferrer"&gt;OpenRouter's model list&lt;/a&gt; for the most current routing options and model strings.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;claude-code-router&lt;/code&gt; package provides a seamless way to use Claude Code through OpenRouter on Linux, giving you absolute flexibility in model selection while drastically cutting costs via prompt caching. By following this guide, you now have a secure, system-integrated proxy bridging Claude Code with OpenRouter's API infrastructure.&lt;/p&gt;

&lt;p&gt;For additional help, consult the package's documentation on npm or GitHub, and periodically check OpenRouter's documentation for API changes or new model additions.&lt;/p&gt;

</description>
      <category>claude</category>
      <category>openrouter</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Building a Lua docker environment</title>
      <dc:creator>Mike Buyco</dc:creator>
      <pubDate>Sat, 30 Mar 2024 08:48:14 +0000</pubDate>
      <link>https://dev.to/mbuyco/building-a-lua-docker-environment-4h2e</link>
      <guid>https://dev.to/mbuyco/building-a-lua-docker-environment-4h2e</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;I have a keen interest in containerization, a practice that has significantly streamlined my development workflow. Reflecting on my early days in programming around 2011-2012, I recall encountering a common issue when setting up local development environments. Specifically, during the installation of WAMP, I faced an error indicating that port 3306 (MySQL) was already in use. Upon investigation, I discovered that a previous installation of MySQL for a school project was the culprit, highlighting the challenges of managing dependencies and conflicting software configurations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Motivation
&lt;/h2&gt;

&lt;p&gt;Currently, I am embarking on a journey to learn Lua scripting to complement my son's endeavors in 3D modeling within the Roblox platform. This motivation stems from a desire to actively engage and support his interests, although finding the time amidst other responsibilities remains a challenge. Nevertheless, I am enthusiastic about delving into Lua scripting to enhance our collaborative projects.&lt;/p&gt;

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

&lt;p&gt;To facilitate my exploration of Lua, I adopt a pragmatic approach by leveraging containerization with Docker to create a dedicated development environment. This method ensures isolation from existing system dependencies and simplifies setup and management.&lt;/p&gt;

&lt;p&gt;First, let's build the project structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir ~/learn-lua
cd ~/learn-lua
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, create a &lt;code&gt;Dockerfile&lt;/code&gt; and our &lt;code&gt;main.lua&lt;/code&gt; script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch Dockerfile
touch main.lua
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Dockerfile:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Use a base image with Lua installed
FROM alpine:latest

# Install Lua and LuaRocks
RUN apk --update add lua5.3 lua5.3-dev luarocks5.3

# Optionally, you can install additional Lua packages using LuaRocks
# For example, to install LuaSocket:
# RUN luarocks-5.3 install luasocket

# Set the working directory
WORKDIR /app

# Copy your Lua scripts into the container
COPY . .

# Set the command to run your Lua script when the container starts
CMD ["lua5.3", "main.lua"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;main.lua:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;print("Hello, Lua!")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now to run the &lt;code&gt;lua&lt;/code&gt; script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker build -t game-lua .
docker run -it --rm game-lua
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Time to learn more &lt;code&gt;lua&lt;/code&gt;! I will update again soon :D&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Creating a simple CLI note app using a shell alias</title>
      <dc:creator>Mike Buyco</dc:creator>
      <pubDate>Sun, 30 Oct 2022 14:11:33 +0000</pubDate>
      <link>https://dev.to/mbuyco/creating-a-simple-cli-note-app-using-a-shell-alias-3go5</link>
      <guid>https://dev.to/mbuyco/creating-a-simple-cli-note-app-using-a-shell-alias-3go5</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;I've been using the terminal for my work as a software engineer for several years now and really love the idea of doing most of my tasks in the terminal. I mainly use &lt;code&gt;vim&lt;/code&gt; as my IDE and have spent lots of time configuring it to my work style and to improve my productivity over the years. &lt;/p&gt;

&lt;p&gt;Don't get me wrong, I love tools like VSCode (especially the &lt;a href="https://vscode.dev" rel="noopener noreferrer"&gt;web version&lt;/a&gt;) and I started out using text editors like Notepad++ and Sublime Text 2. But when I learned how to use &lt;code&gt;vim&lt;/code&gt; and configure it to become a full-fledged IDE for everyday use, I fell in love with it. Back then I was really looking into how I can write code with minimal overhead as possible.&lt;/p&gt;

&lt;p&gt;Some might say, I'm an old school kind of guy and I'd happily take it as a compliment! &lt;/p&gt;

&lt;p&gt;Enough with the backstory, let's see how we can take note-taking capabilities into the terminal...&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Vim 8+ or Neovim 0.5+&lt;/li&gt;
&lt;li&gt;Unix shell&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Creating an alias
&lt;/h2&gt;

&lt;p&gt;If you're using bash, add this line to your &lt;code&gt;.bashrc&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Quickly create a note file for today
NOTES_FILENAME="notes-$(date +%Y%m%d).txt"
alias notes="mkdir ~/notes &amp;amp;&amp;gt; /dev/null; touch ~/notes/$NOTES_FILENAME; cd ~/notes; vim ~/notes/$NOTES_FILENAME"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's explain the script above...&lt;/p&gt;

&lt;p&gt;First off, we create a &lt;code&gt;NOTES_FILENAME&lt;/code&gt; variable with the current date formatted into the filename. So for example, today is October 10, 2022, then the file &lt;code&gt;notes-20221010.txt&lt;/code&gt; would be created.&lt;/p&gt;

&lt;p&gt;Second, we pass that variable to the &lt;code&gt;alias notes=&lt;/code&gt; declaration. To learn more about aliases, check out &lt;a href="https://www.geeksforgeeks.org/alias-command-in-linux-with-examples/" rel="noopener noreferrer"&gt;this article&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;alias notes=&lt;/code&gt; declaration is like a shortcut for a shell command. So instead of running the actual commands, you save it into a command named &lt;code&gt;notes&lt;/code&gt;. In this case, this command does 4 things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It creates a folder named notes, into the current user's home directory (&lt;code&gt;~/notes&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;It creates a file with the name based on the &lt;code&gt;NOTES_FILENAME&lt;/code&gt; variable we created earlier.&lt;/li&gt;
&lt;li&gt;It cds into the &lt;code&gt;~/notes&lt;/code&gt; directory.&lt;/li&gt;
&lt;li&gt;Runs the &lt;code&gt;vim&lt;/code&gt; text editor for the file we created.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Notes environment
&lt;/h3&gt;

&lt;p&gt;Now we can access our notes by just running the &lt;code&gt;notes&lt;/code&gt; command in the terminal.&lt;/p&gt;

&lt;p&gt;If you have configured &lt;code&gt;vim&lt;/code&gt; to have a fuzzy search for project files or live grepping action, you should be able to search through your notes. And given the date format we mentioned earlier, you can search by file for a specific date. Simple enough yeah? LGTM!&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;The steps we did above is a very simple example of how we can  quickly create notes in the terminal and focus on writing what's on our mind fast without leaving the terminal. If you're like me and you mostly work on the terminal and use &lt;code&gt;vim&lt;/code&gt; as your text editor, this is a very handy tool, simple and practical.&lt;/p&gt;

&lt;p&gt;Let me know your thoughts about this. Cheers!&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%2F1ok3j7gp3ezfvcgwzz7c.gif" 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%2F1ok3j7gp3ezfvcgwzz7c.gif" alt=" " width="200" height="153"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>terminal</category>
      <category>tutorial</category>
      <category>bash</category>
      <category>linux</category>
    </item>
  </channel>
</rss>
