<?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>Forem: Jiordi Viera</title>
    <description>The latest articles on Forem by Jiordi Viera (@jiordiviera).</description>
    <link>https://forem.com/jiordiviera</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%2F1460153%2Fdcfee32d-0781-4554-bbd3-10d5d1be248d.png</url>
      <title>Forem: Jiordi Viera</title>
      <link>https://forem.com/jiordiviera</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/jiordiviera"/>
    <language>en</language>
    <item>
      <title>I built a Laravel package to stop silent cron failures</title>
      <dc:creator>Jiordi Viera</dc:creator>
      <pubDate>Wed, 10 Dec 2025 17:21:30 +0000</pubDate>
      <link>https://forem.com/jiordiviera/i-built-a-laravel-package-to-stop-silent-cron-failures-1o25</link>
      <guid>https://forem.com/jiordiviera/i-built-a-laravel-package-to-stop-silent-cron-failures-1o25</guid>
      <description>&lt;p&gt;My backup job failed at 3 AM last month. I found out on Monday when a client asked why their data wasn't updated.&lt;/p&gt;

&lt;p&gt;This kept happening. Sync tasks stuck for hours. Report generation failing silently. No notifications, no logs I could easily check.&lt;/p&gt;

&lt;p&gt;So I built something to fix it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I built
&lt;/h2&gt;

&lt;p&gt;Laravel Smart Scheduler tracks every scheduled task execution automatically. Install it, and you get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Execution history for every task&lt;/li&gt;
&lt;li&gt;Stuck task detection (when server crashes mid-task)&lt;/li&gt;
&lt;li&gt;Email notifications on failure&lt;/li&gt;
&lt;li&gt;Overlap prevention with visibility
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require jiordiviera/laravel-smart-scheduler
php artisan vendor:publish &lt;span class="nt"&gt;--tag&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;smart-scheduler-migrations
php artisan migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No changes to your existing tasks. It hooks into Laravel's events.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;Every execution gets recorded:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Jiordiviera\SmartScheduler\LaravelSmartScheduler\Models\ScheduleRun&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Recent executions&lt;/span&gt;
&lt;span class="nv"&gt;$runs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ScheduleRun&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;latest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'started_at'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// What failed&lt;/span&gt;
&lt;span class="nv"&gt;$failed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ScheduleRun&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'status'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ScheduleRun&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;STATUS_FAILED&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each record has: task identifier, status, start/end time, duration, output, exception message, server name.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stuck task detection
&lt;/h2&gt;

&lt;p&gt;This is the feature I needed most.&lt;/p&gt;

&lt;p&gt;When your server crashes or a process gets killed, the task stays in "starting" status. Next run sees an overlap and skips. Your task never runs again until you manually fix it.&lt;/p&gt;

&lt;p&gt;Smart Scheduler detects this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// config/smart-scheduler.php&lt;/span&gt;
&lt;span class="s1"&gt;'stuck_timeout_minutes'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When a new execution starts, it checks for old "starting" tasks past the timeout, marks them as "stuck", notifies you, and lets the new execution proceed.&lt;/p&gt;

&lt;p&gt;You can also run it manually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan smart-scheduler:detect-stuck
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Notifications
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// config/smart-scheduler.php&lt;/span&gt;
&lt;span class="s1"&gt;'notifications'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s1"&gt;'email'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s1"&gt;'recipients'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'admin@example.com'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s1"&gt;'notify_on_stuck'&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or in your .env:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SMART_SCHEDULER_EMAIL_RECIPIENTS=admin@example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setup I recommend
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// routes/console.php&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Support\Facades\Schedule&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Clean old records weekly&lt;/span&gt;
&lt;span class="nc"&gt;Schedule&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'smart-scheduler:purge'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;weekly&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Detect stuck tasks every 30 minutes&lt;/span&gt;
&lt;span class="nc"&gt;Schedule&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'smart-scheduler:detect-stuck'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;everyThirtyMinutes&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Custom notifications
&lt;/h2&gt;

&lt;p&gt;Want Slack instead of email? Implement the interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Jiordiviera\SmartScheduler\LaravelSmartScheduler\Contracts\SmartNotifierInterface&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SlackNotifier&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;SmartNotifierInterface&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;sendFailureNotification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;ScheduleRun&lt;/span&gt; &lt;span class="nv"&gt;$run&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Your Slack logic&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;sendStuckNotification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;ScheduleRun&lt;/span&gt; &lt;span class="nv"&gt;$run&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Your Slack logic&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// In a service provider&lt;/span&gt;
&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;singleton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SmartNotifierInterface&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;SlackNotifier&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;PHP 8.2+&lt;/li&gt;
&lt;li&gt;Laravel 11 or 12&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/jiordiviera/laravel-smart-scheduler" rel="noopener noreferrer"&gt;jiordiviera/laravel-smart-scheduler&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Packagist: &lt;a href="https://packagist.org/packages/jiordiviera/laravel-smart-scheduler" rel="noopener noreferrer"&gt;jiordiviera/laravel-smart-scheduler&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;If this is useful to you, a star on GitHub helps.&lt;/p&gt;

&lt;p&gt;What do you use to monitor your scheduled tasks?&lt;/p&gt;

</description>
      <category>php</category>
      <category>laravel</category>
      <category>opensource</category>
      <category>webdev</category>
    </item>
    <item>
      <title>L'Injection de Dépendances (DI) : Comment le Service Container de Laravel Vous Rend Invincible</title>
      <dc:creator>Jiordi Viera</dc:creator>
      <pubDate>Tue, 11 Nov 2025 22:53:04 +0000</pubDate>
      <link>https://forem.com/jiordiviera/linjection-de-dependances-di-comment-le-service-container-de-laravel-vous-rend-invincible-eo0</link>
      <guid>https://forem.com/jiordiviera/linjection-de-dependances-di-comment-le-service-container-de-laravel-vous-rend-invincible-eo0</guid>
      <description>&lt;p&gt;Avouons-le : quand on commence avec Laravel, on voit le terme &lt;strong&gt;"Injection de Dépendances" (DI)&lt;/strong&gt;, on lève les yeux au ciel, et on se dit que c'est du jargon d'architecte. Erreur monumentale! La DI, c'est le &lt;strong&gt;super-pouvoir&lt;/strong&gt; que le &lt;strong&gt;Service Container&lt;/strong&gt; de Laravel vous donne pour écrire du code qui ne vous fera pas hurler à 3h du matin.&lt;/p&gt;

&lt;p&gt;Oubliez la théorie. Concentrons-nous sur un seul objectif : écrire du code &lt;strong&gt;flexible&lt;/strong&gt; et &lt;strong&gt;facile à tester&lt;/strong&gt;. Prêt ? C'est parti.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Le Couplage Fort : Le Ciment qui Tue Votre Code
&lt;/h2&gt;

&lt;p&gt;Pourquoi se compliquer la vie ? Regardez ce code qui semble simple, mais qui est un véritable piège.&lt;/p&gt;

&lt;h3&gt;
  
  
  🛑 Le Piège du "Je me débrouille tout seul"
&lt;/h3&gt;

&lt;p&gt;Imaginez un service qui doit gérer le paiement.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderProcessor&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Order&lt;/span&gt; &lt;span class="nv"&gt;$order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// ❌ Problème : Le OrderProcessor est collé à Stripe.&lt;/span&gt;
        &lt;span class="nv"&gt;$gateway&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;StripePaymentGateway&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; 
        &lt;span class="nv"&gt;$gateway&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;charge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$order&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;total&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Pourquoi ce code est toxique ?&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Changement = Catastrophe :&lt;/strong&gt; Votre boss arrive : "On passe à PayPal la semaine prochaine !". Vous devez aller modifier &lt;strong&gt;directement&lt;/strong&gt; ce fichier. Et s'il y a 20 endroits qui utilisent &lt;code&gt;StripePaymentGateway&lt;/code&gt; ? 😩&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Tester est un cauchemar :&lt;/strong&gt; Comment tester la logique de &lt;code&gt;process()&lt;/code&gt; sans déclencher un &lt;strong&gt;vrai&lt;/strong&gt; paiement chez Stripe ? Vos tests unitaires deviennent des tests d'intégration, ils sont lents, chers, et dépendent d'une connexion Internet.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Le principe pour s'en sortir ? L'&lt;strong&gt;Inversion de Contrôle (IoC)&lt;/strong&gt;. Au lieu que votre classe crie "Je veux Stripe!", c'est le système qui lui dit : "Tiens, voilà ton outil de paiement. Utilise-le."&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Le Service Container : Le Cerveau de Laravel
&lt;/h2&gt;

&lt;p&gt;Le Service Container est l'&lt;strong&gt;usine centralisée&lt;/strong&gt; qui gère cette inversion de contrôle. Il sait comment construire chaque objet et où le livrer.&lt;/p&gt;

&lt;h3&gt;
  
  
  A. La Magie Noire : La Résolution Automatique
&lt;/h3&gt;

&lt;p&gt;Vous utilisez la DI tous les jours sans vous en rendre compte. C'est la forme la plus simple, basée sur le &lt;em&gt;type-hinting&lt;/em&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderProcessor&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;StripePaymentGateway&lt;/span&gt; &lt;span class="nv"&gt;$gateway&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// ✨ Le Conteneur voit 'StripePaymentGateway', le crée et l'injecte.&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;StripePaymentGateway&lt;/span&gt; &lt;span class="nv"&gt;$gateway&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;gateway&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$gateway&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Boom!&lt;/strong&gt; Laravel a lu votre besoin, l'a résolu, et vous l'a servi sur un plateau d'argent.&lt;/p&gt;

&lt;h3&gt;
  
  
  B. Le Saint Graal : Les Bindings et les Interfaces
&lt;/h3&gt;

&lt;p&gt;C'est la partie qui sépare les amateurs des pros. Le code ci-dessus est bien, mais il est toujours attaché à la classe &lt;strong&gt;concrète&lt;/strong&gt; &lt;code&gt;StripePaymentGateway&lt;/code&gt;. Pour la flexibilité ultime, il faut dépendre d'une &lt;strong&gt;Interface&lt;/strong&gt; (un contrat).&lt;/p&gt;

&lt;h4&gt;
  
  
  On Configure l'Usine (Dans un Service Provider)
&lt;/h4&gt;

&lt;p&gt;Nos &lt;strong&gt;Service Providers&lt;/strong&gt; sont l'endroit où nous faisons le lien. Nous disons au conteneur : "Quand quelqu'un demande le Contrat (Interface), donne-lui cette Implémentation."&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// App/Providers/AppServiceProvider.php&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Contracts\PaymentGateway&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Services\StripePaymentGateway&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;register&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// 💡 Binding : Demande l'Interface (le "Quoi"), donne l'Implémentation (le "Comment").&lt;/span&gt;
    &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nc"&gt;PaymentGateway&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nc"&gt;StripePaymentGateway&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="c1"&gt;// On peut changer cette ligne pour PayPal&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Le Code de l'OrderProcessor Devient Parfait
&lt;/h4&gt;

&lt;p&gt;Notre processeur ne demande plus Stripe, il demande &lt;strong&gt;N'IMPORTE QUEL&lt;/strong&gt; outil de paiement qui respecte le contrat :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderProcessor&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;PaymentGateway&lt;/span&gt; &lt;span class="nv"&gt;$gateway&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Type-hinting vers l'INTERFACE&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;PaymentGateway&lt;/span&gt; &lt;span class="nv"&gt;$gateway&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// 🥳 C'est le conteneur qui décide si c'est Stripe, PayPal, ou un Mock de test.&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;gateway&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$gateway&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Le bénéfice immédiat :&lt;/strong&gt; Pour tester &lt;code&gt;OrderProcessor&lt;/code&gt;, vous n'avez qu'à injecter un &lt;strong&gt;Mock&lt;/strong&gt; de &lt;code&gt;PaymentGateway&lt;/code&gt; qui simule la réponse de paiement. Vos tests sont rapides, isolés, et fiables.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Le Data Binding : La DI dans l'URL
&lt;/h2&gt;

&lt;p&gt;Laravel étend cette philosophie géniale aux données de la requête via le &lt;strong&gt;Route Model Binding&lt;/strong&gt;. C'est une DI spécifique au contexte web.&lt;/p&gt;

&lt;h3&gt;
  
  
  A. Oubliez les ID avec le Binding Implicite
&lt;/h3&gt;

&lt;p&gt;Combien de fois avez-vous écrit ça ? &lt;code&gt;Post::findOrFail($id);&lt;/code&gt;... Assez !&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// routes/web.php&lt;/span&gt;
&lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/posts/{post}'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;PostController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'show'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="c1"&gt;// App/Http/Controllers/PostController.php&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Post&lt;/span&gt; &lt;span class="nv"&gt;$post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//  Injection directe du modèle !&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Le conteneur a lu l'URL, trouvé le Post correspondant, et l'a injecté. &lt;/span&gt;
    &lt;span class="c1"&gt;// Si le post n'existe pas, Laravel envoie un 404 tout seul. Propre.&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'posts.show'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;compact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'post'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Le conteneur lit le &lt;code&gt;Post $post&lt;/code&gt;, comprend qu'il doit récupérer l'objet depuis la base de données, et l'injecte. C'est la beauté du code déclaratif.&lt;/p&gt;

&lt;h3&gt;
  
  
  B. Le Cas du Slug
&lt;/h3&gt;

&lt;p&gt;Vous ne voulez pas utiliser l'ID ? Pas de problème. Dites à Laravel quelle clé utiliser en ajoutant une seule méthode dans votre modèle :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// App/Models/Post.php&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getRouteKeyName&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s1"&gt;'slug'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// On utilise le 'slug' au lieu de 'id' dans l'URL&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Et ça marche !&lt;/strong&gt; Le Data Binding se mettra à jour automatiquement.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion : Adoptez la Mentalité DI
&lt;/h2&gt;

&lt;p&gt;L'Injection de Dépendances dans Laravel, ce n'est pas une complexité à éviter, c'est l'ensemble d'outils (Conteneur, Bindings, Data Binding) qui vous force à coder avec des &lt;strong&gt;contrats&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Ce passage aux Interfaces et aux Service Providers est ce qui transforme un développeur junior qui suit les tutoriels en un architecte senior capable de bâtir une application modulaire et qui ne craint pas le changement.&lt;/p&gt;

&lt;p&gt;Pour vos prochains services métier (Notifications, Export, Paiement), commencez toujours par définir l'&lt;strong&gt;Interface&lt;/strong&gt; avant l'implémentation. Le Service Container est votre meilleur ami, utilisez-le!&lt;/p&gt;

</description>
      <category>designpatterns</category>
      <category>tutorial</category>
      <category>laravel</category>
      <category>php</category>
    </item>
    <item>
      <title>Laravel Log Cleaner v2.01 - Memory-Efficient Log Management with Compression &amp; Backup</title>
      <dc:creator>Jiordi Viera</dc:creator>
      <pubDate>Thu, 06 Nov 2025 02:57:00 +0000</pubDate>
      <link>https://forem.com/jiordiviera/laravel-log-cleaner-v201-memory-efficient-log-management-with-compression-backup-loc</link>
      <guid>https://forem.com/jiordiviera/laravel-log-cleaner-v201-memory-efficient-log-management-with-compression-backup-loc</guid>
      <description>&lt;h1&gt;
  
  
  Laravel Log Cleaner v2.0 - Memory-Efficient Log Management
&lt;/h1&gt;

&lt;h2&gt;
  
  
  The Problem 🔥
&lt;/h2&gt;

&lt;p&gt;We've all been there: your Laravel app runs fine for weeks, then suddenly your server runs out of disk space. You SSH in, check the logs folder, and find a 5GB &lt;code&gt;laravel.log&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Sound familiar?&lt;/p&gt;

&lt;p&gt;Log files can grow out of control fast, especially in production. But clearing them manually is risky, and heavy monitoring tools like Telescope can slow down your app or even crash your server.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution ✨
&lt;/h2&gt;

&lt;p&gt;I built &lt;a href="https://github.com/jiordiviera/laravel-log-cleaner" rel="noopener noreferrer"&gt;Laravel Log Cleaner&lt;/a&gt; to solve this exact problem. Version 2.0 just launched with major improvements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🧠 &lt;strong&gt;Memory-efficient processing&lt;/strong&gt; - handles multi-GB files without crashing&lt;/li&gt;
&lt;li&gt;📦 &lt;strong&gt;Compression support&lt;/strong&gt; - archive old logs instead of deleting&lt;/li&gt;
&lt;li&gt;🔒 &lt;strong&gt;Backup creation&lt;/strong&gt; - never lose important data&lt;/li&gt;
&lt;li&gt;🎯 &lt;strong&gt;Log level filtering&lt;/strong&gt; - keep only ERROR logs, discard the rest&lt;/li&gt;
&lt;li&gt;👀 &lt;strong&gt;Dry-run mode&lt;/strong&gt; - preview changes before applying&lt;/li&gt;
&lt;li&gt;⚡ &lt;strong&gt;50%+ performance improvement&lt;/strong&gt; on large files&lt;/li&gt;
&lt;/ul&gt;

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



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require jiordiviera/laravel-log-cleaner
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it! No config files, no service providers to register. Laravel's auto-discovery handles everything.&lt;/p&gt;

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

&lt;p&gt;Clear all logs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan log:clear
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keep the last 30 days:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan log:clear &lt;span class="nt"&gt;--days&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;30
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Advanced Features (What's New in v2.0)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Safe Operations 🔒
&lt;/h3&gt;

&lt;p&gt;Preview what will be deleted without actually deleting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan log:clear &lt;span class="nt"&gt;--days&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;30 &lt;span class="nt"&gt;--dry-run&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;[DRY RUN] Would remove 15,420 lines from laravel.log
[DRY RUN] Estimated space to free: 45.2 MB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a backup before cleaning:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan log:clear &lt;span class="nt"&gt;--days&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;30 &lt;span class="nt"&gt;--backup&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;Backup created: storage/logs/laravel.log.backup.2024-11-05-14-30-15
Logs older than 30 days have been removed.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Compression Instead of Deletion 📦
&lt;/h3&gt;

&lt;p&gt;Archive old logs for compliance or audit purposes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan log:clear &lt;span class="nt"&gt;--days&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;30 &lt;span class="nt"&gt;--compress&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates &lt;code&gt;laravel.log.old.2024-11-05.gz&lt;/code&gt; - perfect for when you need to keep logs but save disk space.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Log Level Filtering 🎯
&lt;/h3&gt;

&lt;p&gt;Keep only critical errors, discard everything else:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan log:clear &lt;span class="nt"&gt;--days&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0 &lt;span class="nt"&gt;--level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ERROR
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is &lt;strong&gt;huge&lt;/strong&gt; for production. Most of your logs are probably DEBUG or INFO - useful during development but just noise after a few days in production.&lt;/p&gt;

&lt;p&gt;Supported levels: &lt;code&gt;DEBUG&lt;/code&gt;, &lt;code&gt;INFO&lt;/code&gt;, &lt;code&gt;WARNING&lt;/code&gt;, &lt;code&gt;ERROR&lt;/code&gt;, &lt;code&gt;CRITICAL&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Memory-Efficient Processing 🧠
&lt;/h3&gt;

&lt;p&gt;The game-changer for huge log files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan log:clear &lt;span class="nt"&gt;--days&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;30 &lt;span class="nt"&gt;--memory-efficient&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Before v2.0:&lt;/strong&gt; A 2GB log file would crash PHP with "out of memory" errors&lt;br&gt;&lt;br&gt;
&lt;strong&gt;After v2.0:&lt;/strong&gt; Processes the same file using stream processing, never loads more than 50MB in RAM&lt;/p&gt;

&lt;p&gt;The package automatically detects large files (&amp;gt;50MB) and enables memory-efficient mode, but you can force it with this flag.&lt;/p&gt;
&lt;h3&gt;
  
  
  5. Custom Date Patterns 🔍
&lt;/h3&gt;

&lt;p&gt;Got non-standard log formats? No problem:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan log:clear &lt;span class="nt"&gt;--days&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;30 &lt;span class="nt"&gt;--pattern&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/^(&lt;/span&gt;&lt;span class="se"&gt;\d&lt;/span&gt;&lt;span class="s2"&gt;{4}-&lt;/span&gt;&lt;span class="se"&gt;\d&lt;/span&gt;&lt;span class="s2"&gt;{2}-&lt;/span&gt;&lt;span class="se"&gt;\d&lt;/span&gt;&lt;span class="s2"&gt;{2})/"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6. Combine Everything 🚀
&lt;/h3&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan log:clear &lt;span class="nt"&gt;--days&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;30 &lt;span class="nt"&gt;--backup&lt;/span&gt; &lt;span class="nt"&gt;--compress&lt;/span&gt; &lt;span class="nt"&gt;--level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ERROR &lt;span class="nt"&gt;--dry-run&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Previews what would be deleted (dry-run)&lt;/li&gt;
&lt;li&gt;Creates a backup before making changes&lt;/li&gt;
&lt;li&gt;Compresses old logs instead of deleting&lt;/li&gt;
&lt;li&gt;Keeps only ERROR level logs&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Real-World Use Case
&lt;/h2&gt;

&lt;p&gt;Here's how I use it in production:&lt;/p&gt;

&lt;h3&gt;
  
  
  Laravel 11+ (Current)
&lt;/h3&gt;

&lt;p&gt;Schedule in &lt;code&gt;routes/console.php&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Support\Facades\Schedule&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Every day at 2 AM - keep 7 days of ERROR logs&lt;/span&gt;
&lt;span class="nc"&gt;Schedule&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'log:clear'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s1"&gt;'--days'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'--backup'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'--level'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'ERROR'&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;daily&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;at&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'02:00'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Weekly deep clean with compression&lt;/span&gt;
&lt;span class="nc"&gt;Schedule&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'log:clear'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s1"&gt;'--days'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'--compress'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;weekly&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;sundays&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;at&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'03:00'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Laravel 10 and Below
&lt;/h3&gt;

&lt;p&gt;Schedule in &lt;code&gt;app/Console/Kernel.php&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;schedule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Schedule&lt;/span&gt; &lt;span class="nv"&gt;$schedule&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$schedule&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'log:clear'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s1"&gt;'--days'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'--backup'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'--level'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'ERROR'&lt;/span&gt;
    &lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;daily&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;at&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'02:00'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nv"&gt;$schedule&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'log:clear'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s1"&gt;'--days'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'--compress'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;weekly&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;sundays&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;at&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'03:00'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Result:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;✅ Keeps 7 days of ERROR logs for quick debugging&lt;/li&gt;
&lt;li&gt;✅ Archives everything older in compressed format&lt;/li&gt;
&lt;li&gt;✅ Never runs out of disk space&lt;/li&gt;
&lt;li&gt;✅ No manual intervention needed&lt;/li&gt;
&lt;li&gt;✅ Backups created automatically&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Performance Benchmarks 📊
&lt;/h2&gt;

&lt;p&gt;I tested this on a real production log file from one of my client's projects:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test File:&lt;/strong&gt; 1.2 GB, 3.5 million lines&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;v1.0&lt;/th&gt;
&lt;th&gt;v2.0&lt;/th&gt;
&lt;th&gt;Improvement&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Clear all logs&lt;/td&gt;
&lt;td&gt;45s&lt;/td&gt;
&lt;td&gt;12s&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;73% faster&lt;/strong&gt; ⚡&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Filter by date (30 days)&lt;/td&gt;
&lt;td&gt;Memory error ❌&lt;/td&gt;
&lt;td&gt;18s&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Now possible&lt;/strong&gt; ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory usage (peak)&lt;/td&gt;
&lt;td&gt;512MB+&lt;/td&gt;
&lt;td&gt;48MB&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;90% reduction&lt;/strong&gt; 🎯&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Compression&lt;/td&gt;
&lt;td&gt;Not supported&lt;/td&gt;
&lt;td&gt;8s&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;New feature&lt;/strong&gt; 🆕&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Why Not Use X? 🤔
&lt;/h2&gt;

&lt;h3&gt;
  
  
  vs. Manual deletion (&lt;code&gt;rm laravel.log&lt;/code&gt; or &lt;code&gt;echo "" &amp;gt; laravel.log&lt;/code&gt;)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;❌ No selective date filtering&lt;/li&gt;
&lt;li&gt;❌ Risk of deleting current day's logs&lt;/li&gt;
&lt;li&gt;❌ No backup option&lt;/li&gt;
&lt;li&gt;❌ Can't filter by log level&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  vs. Laravel Telescope
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;❌ Telescope is heavy (database overhead, UI, background jobs)&lt;/li&gt;
&lt;li&gt;❌ Can actually slow down your app in production&lt;/li&gt;
&lt;li&gt;✅ Laravel Log Cleaner has &lt;strong&gt;zero runtime overhead&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;✅ Only runs when you schedule it&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  vs. Other log cleaner packages
&lt;/h3&gt;

&lt;p&gt;Most alternatives:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❌ Don't handle memory efficiently (crash on large files)&lt;/li&gt;
&lt;li&gt;❌ No compression support&lt;/li&gt;
&lt;li&gt;❌ No log level filtering&lt;/li&gt;
&lt;li&gt;❌ No dry-run mode for safety&lt;/li&gt;
&lt;li&gt;❌ Limited or no backup functionality&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Compatibility
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Current Version (v2.x):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PHP 8.1, 8.2, 8.3+&lt;/li&gt;
&lt;li&gt;Laravel 9.x, 10.x, 11.x, 12.x&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Legacy Support (v1.x):&lt;/strong&gt;&lt;br&gt;
If you're still on older versions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require jiordiviera/laravel-log-cleaner:^1.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;PHP 7.0+&lt;/li&gt;
&lt;li&gt;Laravel 7.x, 8.x&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Migration from v1.x
&lt;/h2&gt;

&lt;p&gt;Upgrading from v1.x? It's seamless!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; Update via Composer&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer update jiordiviera/laravel-log-cleaner
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2:&lt;/strong&gt; Check PHP/Laravel requirements&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Requires PHP 8.1+&lt;/li&gt;
&lt;li&gt;Requires Laravel 9+&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 3:&lt;/strong&gt; Enjoy new features!&lt;br&gt;
All your existing commands still work. The new features are opt-in via command flags.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Breaking changes:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dropped PHP 7.x support&lt;/li&gt;
&lt;li&gt;Dropped Laravel 7.x and 8.x support&lt;/li&gt;
&lt;li&gt;If you need these versions, stay on v1.x&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Common Use Cases
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Development: Keep Recent Logs Only
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan log:clear &lt;span class="nt"&gt;--days&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Production: Aggressive Cleanup with Safety
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan log:clear &lt;span class="nt"&gt;--days&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;7 &lt;span class="nt"&gt;--backup&lt;/span&gt; &lt;span class="nt"&gt;--level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ERROR
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Compliance: Archive Everything
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan log:clear &lt;span class="nt"&gt;--days&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;90 &lt;span class="nt"&gt;--compress&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Emergency: Server Running Out of Space
&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;# Preview impact first&lt;/span&gt;
php artisan log:clear &lt;span class="nt"&gt;--days&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1 &lt;span class="nt"&gt;--dry-run&lt;/span&gt;

&lt;span class="c"&gt;# If safe, execute&lt;/span&gt;
php artisan log:clear &lt;span class="nt"&gt;--days&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1 &lt;span class="nt"&gt;--backup&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. CI/CD Pipeline: Clean After Tests
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan log:clear &lt;span class="nt"&gt;--days&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What's Next? 🔮
&lt;/h2&gt;

&lt;p&gt;I'm considering these features for future releases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🗂️ Multiple log file support (&lt;code&gt;--file=api.log&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;📧 Slack/Email notifications on cleanup completion&lt;/li&gt;
&lt;li&gt;⚙️ Config file for environment-specific retention policies&lt;/li&gt;
&lt;li&gt;☁️ Cloud storage integration (S3, GCS, Azure)&lt;/li&gt;
&lt;li&gt;📊 Log analytics before cleanup (show stats)&lt;/li&gt;
&lt;li&gt;🔄 Auto-rotation based on file size (not just days)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What would YOU like to see?&lt;/strong&gt; Drop a comment below! Your feedback shapes the roadmap.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It Out
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require jiordiviera/laravel-log-cleaner
php artisan log:clear &lt;span class="nt"&gt;--help&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📦 &lt;a href="https://packagist.org/packages/jiordiviera/laravel-log-cleaner" rel="noopener noreferrer"&gt;Packagist&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🐙 &lt;a href="https://github.com/jiordiviera/laravel-log-cleaner" rel="noopener noreferrer"&gt;GitHub Repository&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;⭐ Star on GitHub if you find it useful!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Contributing
&lt;/h2&gt;

&lt;p&gt;Found a bug? Have a feature request? Contributions are welcome!&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Fork the repo&lt;/li&gt;
&lt;li&gt;Create a feature branch&lt;/li&gt;
&lt;li&gt;Write tests (we use Pest)&lt;/li&gt;
&lt;li&gt;Submit a PR&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Check out the &lt;a href="https://github.com/jiordiviera/laravel-log-cleaner/blob/main/CONTRIBUTING.md" rel="noopener noreferrer"&gt;Contributing Guide&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  About Me
&lt;/h2&gt;

&lt;p&gt;I'm Jiordi Viera, a fullstack developer from Douala, Cameroon 🇨🇲. I work primarily with Laravel, Next.js, and React. &lt;/p&gt;

&lt;p&gt;I built this package after dealing with production log issues one too many times. What started as a simple script evolved into a full package when I realized others had the same problem.&lt;/p&gt;

&lt;p&gt;If this package helps you, consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⭐ Starring the &lt;a href="https://github.com/jiordiviera/laravel-log-cleaner" rel="noopener noreferrer"&gt;GitHub repo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📢 Sharing this article&lt;/li&gt;
&lt;li&gt;☕ Buying me a coffee (if you're feeling generous)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Connect with me:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🌐 Website: &lt;a href="https://jiordiviera.me" rel="noopener noreferrer"&gt;jiordiviera.me&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🐙 GitHub: &lt;a href="https://github.com/jiordiviera" rel="noopener noreferrer"&gt;@jiordiviera&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💼 LinkedIn: [Add your LinkedIn if you have one]&lt;/li&gt;
&lt;li&gt;🐦 Twitter/X: [Add your handle if you have one]&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Other projects:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://codepit.jiordiviera.me" rel="noopener noreferrer"&gt;Codepit&lt;/a&gt; - A minimal platform to share code snippets&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Thanks for reading! If you found this helpful, please leave a ❤️ and share your experience in the comments below.&lt;/p&gt;

&lt;p&gt;Happy logging! 🚀&lt;/p&gt;

&lt;h1&gt;
  
  
  Laravel #PHP #OpenSource #DevOps #WebDev #BackendDevelopment
&lt;/h1&gt;

</description>
      <category>php</category>
      <category>laravel</category>
      <category>opensource</category>
      <category>devops</category>
    </item>
    <item>
      <title>Introducing Codepit: A Minimal Platform to Share Code Snippets</title>
      <dc:creator>Jiordi Viera</dc:creator>
      <pubDate>Fri, 05 Sep 2025 15:09:13 +0000</pubDate>
      <link>https://forem.com/jiordiviera/introducing-codepit-a-minimal-platform-to-share-code-snippets-10bc</link>
      <guid>https://forem.com/jiordiviera/introducing-codepit-a-minimal-platform-to-share-code-snippets-10bc</guid>
      <description>&lt;h1&gt;
  
  
  Introducing Codepit: A Minimal Platform to Share Code Snippets
&lt;/h1&gt;

&lt;p&gt;Every developer has a collection of small code snippets saved somewhere — in notes, gists, or random files.&lt;br&gt;&lt;br&gt;
But when it comes to organizing, reusing, and sharing them, things can quickly get messy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Codepit&lt;/strong&gt; is a minimal and fast platform to create, share, and organize code snippets in a structured way.&lt;br&gt;&lt;br&gt;
You can try it here: &lt;a href="https://codepit.jiordiviera.me" rel="noopener noreferrer"&gt;https://codepit.jiordiviera.me&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Create and edit snippets with language selection and syntax highlighting
&lt;/li&gt;
&lt;li&gt;Organize snippets into collections (public or private)
&lt;/li&gt;
&lt;li&gt;Explore and discover snippets by tags, language, or author
&lt;/li&gt;
&lt;li&gt;Comments, likes, and view counts
&lt;/li&gt;
&lt;li&gt;OAuth authentication (guests can browse, sign-in required for interactions)
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Tech Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Next.js (App Router) + React + TypeScript
&lt;/li&gt;
&lt;li&gt;TailwindCSS v4 with design tokens
&lt;/li&gt;
&lt;li&gt;Prisma + PostgreSQL
&lt;/li&gt;
&lt;li&gt;Monaco Editor for editing, Shiki/Prism for highlighting
&lt;/li&gt;
&lt;li&gt;Better Auth for authentication
&lt;/li&gt;
&lt;li&gt;Bun as runtime
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Screenshots
&lt;/h2&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%2Fi19papcw8y1stcrcvqp5.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%2Fi19papcw8y1stcrcvqp5.png" alt=" " width="800" height="450"&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%2Fcajdkggqm06sy0fu4n6n.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%2Fcajdkggqm06sy0fu4n6n.png" alt=" " width="800" height="352"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Roadmap
&lt;/h2&gt;

&lt;p&gt;Planned improvements include:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Public collections gallery with filters
&lt;/li&gt;
&lt;li&gt;Rich open graph images per snippet
&lt;/li&gt;
&lt;li&gt;Like support for comments
&lt;/li&gt;
&lt;li&gt;Rate-limiting for comment and view tracking
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Feedback
&lt;/h2&gt;

&lt;p&gt;Codepit is focused on staying minimal and practical.&lt;br&gt;&lt;br&gt;
I’d love to hear your thoughts:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which features matter most to you when managing snippets?
&lt;/li&gt;
&lt;li&gt;Would you use it for public sharing or private storage?
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Comments and suggestions are very welcome.  &lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>opensource</category>
      <category>productivity</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
