<?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: Palks Studio</title>
    <description>The latest articles on DEV Community by Palks Studio (@palks_studio).</description>
    <link>https://dev.to/palks_studio</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%2F3772766%2Ffab897d4-6d2e-4fe9-9350-3e9fa72aec4e.png</url>
      <title>DEV Community: Palks Studio</title>
      <link>https://dev.to/palks_studio</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/palks_studio"/>
    <language>en</language>
    <item>
      <title>Static websites don’t limit features. They redefine where complexity lives</title>
      <dc:creator>Palks Studio</dc:creator>
      <pubDate>Fri, 17 Apr 2026 15:10:23 +0000</pubDate>
      <link>https://dev.to/palks_studio/static-websites-dont-limit-features-they-redefine-where-complexity-lives-37kh</link>
      <guid>https://dev.to/palks_studio/static-websites-dont-limit-features-they-redefine-where-complexity-lives-37kh</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9iv2snnsbo660krm5xdw.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%2F9iv2snnsbo660krm5xdw.png" alt="Palks Studio homepage — static" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Static Websites Are Not Limited Websites
&lt;/h2&gt;

&lt;p&gt;Static websites are often associated with simple projects: landing pages, fixed content, or minimal websites without advanced functionality.&lt;/p&gt;

&lt;p&gt;This perception largely comes from earlier stages of the web, where “static” meant limited interaction and little or no logic.&lt;/p&gt;

&lt;p&gt;Today, that association no longer reflects reality.&lt;/p&gt;

&lt;p&gt;A static website does not define what a project can do, but how it is structured.&lt;/p&gt;




&lt;h2&gt;
  
  
  Static does not mean minimal
&lt;/h2&gt;

&lt;p&gt;A static website can integrate many modern features:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;secure download systems
&lt;/li&gt;
&lt;li&gt;payments handled through external services
&lt;/li&gt;
&lt;li&gt;interactive interfaces
&lt;/li&gt;
&lt;li&gt;local chatbots
&lt;/li&gt;
&lt;li&gt;client-side animations and dynamic behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The difference is not in visible capabilities, but in where complexity is placed.&lt;/p&gt;

&lt;p&gt;Instead of concentrating logic in a permanent server or database, functionality is isolated into specific components only where it is needed.&lt;/p&gt;




&lt;h2&gt;
  
  
  Moving complexity instead of spreading it
&lt;/h2&gt;

&lt;p&gt;In many projects, a full backend is introduced by default, even when actual needs remain limited.&lt;/p&gt;

&lt;p&gt;This often increases complexity:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;continuous server maintenance
&lt;/li&gt;
&lt;li&gt;additional dependencies
&lt;/li&gt;
&lt;li&gt;larger error surface
&lt;/li&gt;
&lt;li&gt;constant updates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A static approach keeps the website itself simple while delegating only necessary parts to specialized services or scripts.&lt;/p&gt;

&lt;p&gt;Complexity is not removed.&lt;br&gt;&lt;br&gt;
It is moved to controlled areas.&lt;/p&gt;




&lt;h2&gt;
  
  
  Performance and structural clarity
&lt;/h2&gt;

&lt;p&gt;Static websites also provide structural advantages.&lt;/p&gt;

&lt;p&gt;Content is directly accessible, structure remains readable, and behavior stays predictable. The absence of server-side generation on each request reduces potential failure points and simplifies hosting.&lt;/p&gt;

&lt;p&gt;This structural simplicity makes long-term maintenance and project handover easier.&lt;/p&gt;

&lt;p&gt;The project remains understandable without requiring complex infrastructure.&lt;/p&gt;




&lt;h2&gt;
  
  
  Most real-world needs
&lt;/h2&gt;

&lt;p&gt;In practice, many web projects do not require a fully dynamic system.&lt;/p&gt;

&lt;p&gt;Presentation websites, documentation, digital products, educational content, or information platforms can operate efficiently on a well-designed static foundation.&lt;/p&gt;

&lt;p&gt;Advanced functionality can be added selectively without turning the entire project into a complex application.&lt;/p&gt;




&lt;h2&gt;
  
  
  An engineering choice
&lt;/h2&gt;

&lt;p&gt;Choosing a static architecture is not about limiting a project.&lt;br&gt;&lt;br&gt;
It is often about defining a clear scope, reducing maintenance, and achieving more predictable behavior.&lt;/p&gt;

&lt;p&gt;Static websites do not replace dynamic applications where they are necessary.&lt;br&gt;&lt;br&gt;
But in many cases, they provide a more stable result with less complexity.&lt;/p&gt;

&lt;p&gt;This is not a step backward.&lt;br&gt;&lt;br&gt;
It is a structural decision.&lt;/p&gt;

&lt;p&gt;At Palks Studio, websites are built as static, dependency-free systems. Bases are available here: &lt;a href="https://palks-studio.com/en/static-site" rel="noopener noreferrer"&gt;https://palks-studio.com/en/static-site&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;If you're interested in how it works under the hood:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here’s a technical breakdown of the system architecture.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Palks Studio — Static site + digital storefront
&lt;/h2&gt;

&lt;p&gt;This repository contains the public website of Palks Studio, which combines:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a clean, tracking-free static HTML website
&lt;/li&gt;
&lt;li&gt;a lightweight server-side digital storefront
&lt;/li&gt;
&lt;li&gt;an autonomous PDF invoicing system
&lt;/li&gt;
&lt;li&gt;and secure token-based delivery of downloadable files
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The system operates without a CMS, without a database, and without unnecessary SaaS dependencies,&lt;br&gt;&lt;br&gt;
relying solely on flat files (JSON/CSV) and minimalist PHP scripts.  &lt;/p&gt;

&lt;p&gt;The repository includes:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the public website (pages, styles, images, content)
&lt;/li&gt;
&lt;li&gt;payment and digital delivery components
&lt;/li&gt;
&lt;li&gt;as well as publicly accessible documentation
with the aim of clarity, readability, and transparency
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This repository is not a turnkey product, a framework, or a software library.&lt;br&gt;&lt;br&gt;
It serves as a reference artifact to understand the approach,&lt;br&gt;&lt;br&gt;
tools, and technical choices carried by Palks Studio.  &lt;/p&gt;




&lt;h2&gt;
  
  
  About Palks Studio
&lt;/h2&gt;

&lt;p&gt;Palks Studio designs technical tools, documentation structures,&lt;br&gt;&lt;br&gt;
and working environments intended to be:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;readable
&lt;/li&gt;
&lt;li&gt;understandable
&lt;/li&gt;
&lt;li&gt;autonomous
&lt;/li&gt;
&lt;li&gt;maintainable over time
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The emphasis is placed on:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;functional simplicity
&lt;/li&gt;
&lt;li&gt;control of dependencies
&lt;/li&gt;
&lt;li&gt;transparency of technical choices
&lt;/li&gt;
&lt;li&gt;durability rather than trends
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Project structure
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/palks-studio-website/
│
├── fr/
│   ├── index.html                            → Accueil principal
│   ├── services.html                         → Page de présentation des services
│   ├── facturation-sans-saas.html            → Système de facturation autonome
│   ├── facturation-batch-facturx.html        → Service de facturation batch Factur-X
│   ├── facturation-sans-saas.html            → Service de facturation autonome sans SaaS (devis, factures, paiements)
│   ├── sans-abonnement.html                  → Approche sans abonnement
│   ├── systemes-techniques-autonomes.html    → Développement backend sur mesure
│   ├── studio.html                           → Présentation de Palks Studio
│   ├── approche.html                         → Approche et principes de travail
│   ├── ressources.html                       → Ressources techniques
│   ├── generateur-devis.html                 → Générateur de devis PDF gratuit
│   ├── static-site.html                      → Socle de site statique
│   ├── chatbot-flask.html                    → Chatbot Flask auto-hébergé
│   ├── framework-documentation.html          → Framework de documentation
│   ├── pack-environnement-vscode.html        → Pack environnement VS Code
│   ├── liens.html                            → Liens, ressources, produits
│   ├── mentions-legales.html                 → Mentions légales (FR) / Legal notice (EN)
│   ├── contact.html                          → Page de contact
│   ├── notes-techniques.html*                → Notes techniques
│   ├── cgv.html                              → Conditions générales de vente
│   ├── faq.html                              → Foire aux questions
│   └── politique-confidentialite.html        → Politique de confidentialité (FR) / Privacy policy (EN)    facturation-sans-saas
│
├── en/
│   ├── index.html                            → Home page
│   ├── services.html                         → Services page
│   ├── invoicing-without-saas.html           → Autonomous invoicing system
│   ├── batch-invoicing-facturx.html          → Factur-X batch billing service
│   ├── invoicing-without-saas.html           → Autonomous invoicing service without SaaS (quotes, invoices, payments)
│   ├── no-subscription.html                  → No-subscription approach
│   ├── autonomous-backend-systems.html       → Custom backend development
│   ├── studio.html                           → Studio overview
│   ├── approach.html                         → Method &amp;amp; principles
│   ├── ressources.html                       → Technical resources
│   ├── generateur-devis.html                 → Free PDF quote generator
│   ├── static-site.html                      → Professional static foundation
│   ├── flask-chatbot.html                    → Self-hosted Flask chatbot
│   ├── documentation-framework.html          → Documentation framework
│   ├── vscode-environment-pack.html          → VS Code environment pack
│   ├── links.html                            → Links &amp;amp; resources
│   ├── contact.html                          → Contact page
│   ├── technical-notes.html*                 → Technical notes
│   ├── faq.html                              → Frequently Asked Questions
│   └── terms.html                            → Terms and Conditions
│
├── assets/
│   ├── css/
│   │   └── style.css                         → Global stylesheet (FR) / Feuille de styles globale (EN)
│   └── img/                                  → Images et visuels (FR) / Images and visuals (EN)
│
├── robots.txt                                → Règles pour moteurs de recherche (FR) / Search engine directives (EN)
├── sitemap.xml                               → Plan du site pour indexation (FR) / Sitemap for indexing (EN)
│
├── LICENCE.md                                → Conditions d’utilisation et cadre légal (FR)
├── LICENSE.md                                → Terms of use and legal Framework (EN)
│
├── generate-contract.php                     → Backend génération PDF (FR) / PDF generation backend (EN)
├── upload-batch.php                          → Moteur de traitement du formulaire CSV (FR) / CSV upload form processing engine (EN)
│
├── downloads_tokens/
│   ├── downloads.log                         → Journal des téléchargements réels (FR) / Download activity log (EN)
│   ├── security.log                          → Journal des accès sécurisés aux fichiers (FR) / Secure download access log (EN)
│   └── tokens.json                           → Stockage des tokens de téléchargement (FR) / Download token storage (EN)
│
├── config/
│   └── download.php                          → Configuration centrale des téléchargements (FR) / Central download configuration (EN)
│
├── library/
│   ├── contact-contrat-fr.html               → Génération contrat + configuration client (FR)
│   ├── contact-contrat-en.html               → Contract + client configuration generation (EN)
│   ├── contrat-template-fr.html              → Template de contrat (FR)
│   ├── contrat-template-en.html              → Contract template (EN)
│   ├── upload-batch-fr.html                  → Formulaire d’envoi CSV client (FR)
│   ├── upload-batch-en.html                  → Client CSV upload form (EN)
│   ├── cancel.html                           → Page d’annulation de paiement (FR)/ Payment cancellation page (EN)
│   ├── success.html                          → Page de paiement validé (FR) / Payment success page (EN)
│   ├── counter.json                          → Compteur persistant de factures (FR) / Persistent invoice counter (EN)
│   ├── get_counter.php                       → Lecture sécurisée du compteur de factures (FR) / Secure invoice counter reader (EN)
│   ├── lib_*.php                             → Incrémentation atomique du numéro de facture (FR) / Secure invoice counter reader (EN)
│   ├── lib_*.php                             → Génération HTML des factures (FR) / Atomic invoice number increment (EN)
│   ├── lib_*.php                             → Envoi e-mails transactionnels (FR) / Transactional email delivery (EN)
│   ├── lib_*.php                             → Génération PDF via DomPDF (FR) / PDF generation via DomPDF (EN)
│   └── template_invoice.html                 → Template HTML de facture (FR) / Invoice HTML template (EN)
│
├── docs/
│   ├── VUE_D_ENSEMBLE.md                     → Vue d’ensemble du système (FR)
│   ├── OVERVIEW.md                           → System Overview (EN)
│   ├── PROJECT-OVERVIEW_FR.md                → Vue d’ensemble du projet (FR)
│   ├── PROJECT-OVERVIEW.md                   → Project Overview (EN)
│   ├── README_FR.md                          → Présentation générale (FR)
│   └── README.md                             → General Overview (EN)
│
├── products/
│   └── (store files)                         → Fichiers produits numériques (FR) / Digital product files (EN)
│
└── endpoint/
    ├── endpoint_a.php                        → Initialisation d’une session de paiement (FR) / Checkout session initialization (EN)
    ├── endpoint_b.php                        → Traitement des événements de paiement (FR) / Payment event handler (EN)
    ├── endpoint_c.php                        → Traitement post-paiement (FR) / Post-payment fulfillment handler (EN)
    └── endpoint_d.php                        → Point d’accès sécurisé aux fichiers (FR) / Secure file access endpoint (EN)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to explore the technical implementation, you can find it here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Palks-Studio/palks-studio-website" rel="noopener noreferrer"&gt;https://github.com/Palks-Studio/palks-studio-website&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://palks-studio.com" rel="noopener noreferrer"&gt;https://palks-studio.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>javascript</category>
      <category>backend</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Not All Complexity Is Bad — But Most of It Is</title>
      <dc:creator>Palks Studio</dc:creator>
      <pubDate>Sat, 11 Apr 2026 17:12:47 +0000</pubDate>
      <link>https://dev.to/palks_studio/not-all-complexity-is-bad-but-most-of-it-is-48h</link>
      <guid>https://dev.to/palks_studio/not-all-complexity-is-bad-but-most-of-it-is-48h</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcq3bjnhr9n0o16bciz4n.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%2Fcq3bjnhr9n0o16bciz4n.png" alt="System complexity diagram" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why complexity isn’t always the problem
&lt;/h2&gt;

&lt;p&gt;Complexity is often seen as something to eliminate.&lt;/p&gt;

&lt;p&gt;But not all complexity is bad.&lt;/p&gt;

&lt;p&gt;Some of it is necessary.&lt;/p&gt;

&lt;p&gt;Some of it shouldn’t exist.&lt;/p&gt;




&lt;h2&gt;
  
  
  The confusion
&lt;/h2&gt;

&lt;p&gt;Most systems don’t fail because they are complex.&lt;/p&gt;

&lt;p&gt;They fail because the wrong complexity accumulates.&lt;/p&gt;




&lt;h2&gt;
  
  
  The real issue
&lt;/h2&gt;

&lt;p&gt;Over time, systems mix two things:&lt;/p&gt;

&lt;p&gt;what is required&lt;br&gt;
what just happened to be added&lt;/p&gt;

&lt;p&gt;And the difference disappears.&lt;/p&gt;




&lt;h2&gt;
  
  
  What actually matters
&lt;/h2&gt;

&lt;p&gt;Good systems don’t avoid complexity.&lt;/p&gt;

&lt;p&gt;They make it visible and intentional.&lt;/p&gt;




&lt;h2&gt;
  
  
  A better way to think about it
&lt;/h2&gt;

&lt;p&gt;Instead of asking:&lt;/p&gt;

&lt;p&gt;“how do we simplify?”&lt;/p&gt;

&lt;p&gt;Ask:&lt;/p&gt;

&lt;p&gt;“which complexity belongs here?”&lt;/p&gt;

&lt;p&gt;Full article → &lt;a href="https://palks-studio.com/en/useful-vs-accidental-complexity" rel="noopener noreferrer"&gt;https://palks-studio.com/en/useful-vs-accidental-complexity&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://palks-studio.com" rel="noopener noreferrer"&gt;https://palks-studio.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>software</category>
      <category>architecture</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Factur-X EN16931: your invoice is probably not compliant (and you don't know it)</title>
      <dc:creator>Palks Studio</dc:creator>
      <pubDate>Fri, 03 Apr 2026 17:03:31 +0000</pubDate>
      <link>https://dev.to/palks_studio/factur-x-en16931-your-invoice-is-probably-not-compliant-and-you-dont-know-it-5kj</link>
      <guid>https://dev.to/palks_studio/factur-x-en16931-your-invoice-is-probably-not-compliant-and-you-dont-know-it-5kj</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzegrwknfnnok7u1vruzr.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%2Fzegrwknfnnok7u1vruzr.png" alt="Factur-X EN16931 compliant invoice — XSD, Schematron and PDF/A-3 validated" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most invoicing solutions claim Factur-X compliance.&lt;br&gt;
Few actually pass all three validation levels.&lt;/p&gt;




&lt;h2&gt;
  
  
  The three levels
&lt;/h2&gt;

&lt;p&gt;Factur-X conformity requires passing all of these:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;XSD validation — XML structure is syntactically correct&lt;/li&gt;
&lt;li&gt;Schematron validation — EN16931 business rules are respected&lt;/li&gt;
&lt;li&gt;PDF/A-3 validation — the PDF document is archivable with the XML correctly embedded&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Where most solutions fail
&lt;/h2&gt;

&lt;p&gt;PDF/A-3 is the real problem.&lt;/p&gt;

&lt;p&gt;Common PHP PDF libraries — Dompdf, TCPDF — produce DeviceRGB without ICC OutputIntent.&lt;br&gt;
The XML can be perfectly structured. The invoice is still rejected.&lt;/p&gt;




&lt;h2&gt;
  
  
  The combination that works
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;mPDF generates clean PDF/A-1b output&lt;/li&gt;
&lt;li&gt;factur-x (Python) injects the EN16931 XML and converts to PDF/A-3&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Result: XSD ✅ Schematron ✅ PDF/A-3 ✅&lt;/p&gt;




&lt;p&gt;Full note → &lt;a href="https://palks-studio.com/en/electronic-invoicing-compliance" rel="noopener noreferrer"&gt;https://palks-studio.com/en/electronic-invoicing-compliance&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://palks-studio.com" rel="noopener noreferrer"&gt;https://palks-studio.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>backend</category>
      <category>payments</category>
      <category>php</category>
      <category>software</category>
    </item>
    <item>
      <title>Why real-time can unnecessarily complicate simple systems</title>
      <dc:creator>Palks Studio</dc:creator>
      <pubDate>Wed, 25 Mar 2026 15:55:42 +0000</pubDate>
      <link>https://dev.to/palks_studio/why-real-time-can-unnecessarily-complicate-simple-systems-5579</link>
      <guid>https://dev.to/palks_studio/why-real-time-can-unnecessarily-complicate-simple-systems-5579</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fymcj5rqdpip0gltezksv.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%2Fymcj5rqdpip0gltezksv.png" alt="Real-time vs simplicity" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Real-time architectures are everywhere.&lt;/p&gt;

&lt;p&gt;But not every system needs to be instant.&lt;/p&gt;

&lt;p&gt;In many cases, real-time introduces more complexity than value.&lt;/p&gt;




&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;Most systems today assume everything must update instantly.&lt;/p&gt;

&lt;p&gt;But many business processes don’t need that.&lt;/p&gt;




&lt;h2&gt;
  
  
  The hidden cost
&lt;/h2&gt;

&lt;p&gt;Real-time systems create multiple intermediate states.&lt;/p&gt;

&lt;p&gt;Over time, this makes systems harder to understand and maintain.&lt;/p&gt;




&lt;h2&gt;
  
  
  A simpler approach
&lt;/h2&gt;

&lt;p&gt;Some systems benefit from clear, step-based processing instead:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;data preparation
&lt;/li&gt;
&lt;li&gt;validation
&lt;/li&gt;
&lt;li&gt;processing
&lt;/li&gt;
&lt;li&gt;output
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Full article → &lt;a href="https://palks-studio.com/en/real-time-unnecessary-complexity" rel="noopener noreferrer"&gt;https://palks-studio.com/en/real-time-unnecessary-complexity&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://palks-studio.com" rel="noopener noreferrer"&gt;https://palks-studio.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>backend</category>
      <category>architecture</category>
      <category>automation</category>
      <category>software</category>
    </item>
    <item>
      <title>Stop stacking tools. Build systems that run on their own.</title>
      <dc:creator>Palks Studio</dc:creator>
      <pubDate>Sun, 22 Mar 2026 17:14:05 +0000</pubDate>
      <link>https://dev.to/palks_studio/stop-stacking-tools-build-systems-that-run-on-their-own-2j6n</link>
      <guid>https://dev.to/palks_studio/stop-stacking-tools-build-systems-that-run-on-their-own-2j6n</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flb8nhwiqpcgtnycpk5sz.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%2Flb8nhwiqpcgtnycpk5sz.png" alt="Autonomous billing and automation system running on a self-hosted infrastructure without SaaS dependencies" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Entrepreneurs, freelancers, agencies,&lt;/p&gt;

&lt;p&gt;A complete autonomous system running on your own hosting, without SaaS, subscriptions or external dependencies.&lt;/p&gt;

&lt;p&gt;Are you still stacking tools to run your business?&lt;/p&gt;

&lt;p&gt;Zapier.&lt;br&gt;
Make.&lt;br&gt;
Plugins.&lt;br&gt;
Subscriptions.&lt;br&gt;
Updates.&lt;br&gt;
Dependencies.&lt;/p&gt;

&lt;p&gt;It works…&lt;/p&gt;

&lt;p&gt;until it breaks.&lt;/p&gt;




&lt;p&gt;At Palks Studio, we do the opposite.&lt;/p&gt;

&lt;p&gt;We remove dependencies.&lt;/p&gt;

&lt;p&gt;We deploy systems directly on your infrastructure.&lt;/p&gt;




&lt;p&gt;No SaaS.&lt;br&gt;
No subscriptions.&lt;br&gt;
No surprises.&lt;br&gt;
No updates breaking everything.&lt;/p&gt;




&lt;p&gt;Internal scripts.&lt;/p&gt;

&lt;p&gt;Autonomous tools.&lt;/p&gt;

&lt;p&gt;Systems that run on your own hosting.&lt;/p&gt;




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

&lt;p&gt;quotes → signature → invoicing → payment → revenue tracking&lt;br&gt;
&lt;a href="https://palks-studio.com/en/invoicing-without-saas" rel="noopener noreferrer"&gt;https://palks-studio.com/en/invoicing-without-saas&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;p&gt;CSV → batch processing → structured outputs → automated delivery&lt;br&gt;
&lt;a href="https://palks-studio.com/en/batch-invoicing-facturx" rel="noopener noreferrer"&gt;https://palks-studio.com/en/batch-invoicing-facturx&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Invoicing.&lt;br&gt;
Automation.&lt;br&gt;
Internal tools.&lt;/p&gt;

&lt;p&gt;One goal:&lt;/p&gt;

&lt;p&gt;make it work.&lt;br&gt;
simply.&lt;br&gt;
over time.&lt;/p&gt;




&lt;p&gt;Less tools.&lt;br&gt;
Less complexity.&lt;br&gt;
More control.&lt;/p&gt;




&lt;p&gt;If your system depends on 5 external services,&lt;/p&gt;

&lt;p&gt;it’s not a system.&lt;/p&gt;

&lt;p&gt;It’s a fragile chain.&lt;/p&gt;




&lt;p&gt;There’s another way to build.&lt;/p&gt;

&lt;p&gt;Simpler.&lt;br&gt;
More stable.&lt;br&gt;
Fully controlled.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://github.com/Palks-Studio/palks-studio" rel="noopener noreferrer"&gt;https://github.com/Palks-Studio/palks-studio&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://palks-studio.com" rel="noopener noreferrer"&gt;https://palks-studio.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>automation</category>
      <category>backend</category>
      <category>architecture</category>
      <category>business</category>
    </item>
    <item>
      <title>If your business depends on 5 tools, you don’t have a system</title>
      <dc:creator>Palks Studio</dc:creator>
      <pubDate>Mon, 16 Mar 2026 14:11:23 +0000</pubDate>
      <link>https://dev.to/palks_studio/a-self-hosted-financial-system-for-freelancers-4b27</link>
      <guid>https://dev.to/palks_studio/a-self-hosted-financial-system-for-freelancers-4b27</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frqzp7v4v0je7a5k3iysq.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%2Frqzp7v4v0je7a5k3iysq.png" alt="Clean self-hosted invoice system with PDF preview and paid validation process" width="800" height="411"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Still managing quotes, invoices and payments across multiple tools?
&lt;/h2&gt;

&lt;p&gt;I built a complete financial system that runs on your own domain.&lt;/p&gt;

&lt;p&gt;Not a SaaS.&lt;br&gt;
No subscription.&lt;br&gt;
No critical dependencies.&lt;/p&gt;

&lt;p&gt;The system runs on your own hosting.&lt;/p&gt;

&lt;p&gt;Quotes → online signature → invoicing → payment confirmation → revenue journal.&lt;/p&gt;

&lt;p&gt;Everything is semi-automated.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quote / contract
&lt;/h2&gt;

&lt;p&gt;Simple interface:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;your fixed company details&lt;/li&gt;
&lt;li&gt;client information&lt;/li&gt;
&lt;li&gt;service lines&lt;/li&gt;
&lt;li&gt;currency / VAT&lt;/li&gt;
&lt;li&gt;your fixed banking details&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The PDF is generated directly in the browser and sent to the client by email.&lt;/p&gt;

&lt;p&gt;No data is sent to the server before validation.&lt;/p&gt;

&lt;p&gt;Once the quote is sent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a secure link is sent to the client&lt;/li&gt;
&lt;li&gt;the client can view and sign the quote online&lt;/li&gt;
&lt;li&gt;the quote is archived&lt;/li&gt;
&lt;li&gt;you receive a confirmation email&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The quote then becomes a signed contract.&lt;/p&gt;




&lt;h2&gt;
  
  
  Invoicing
&lt;/h2&gt;

&lt;p&gt;The system includes a smart client lookup.&lt;/p&gt;

&lt;p&gt;You only need to enter a single piece of information:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;email&lt;/li&gt;
&lt;li&gt;SIRET / SIREN&lt;/li&gt;
&lt;li&gt;client name&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and the system automatically retrieves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the client’s details&lt;/li&gt;
&lt;li&gt;their existing quotes (a list is suggested in the quote field)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The most recent quote is automatically suggested.&lt;/p&gt;

&lt;p&gt;You simply select the correct quote from the list.&lt;/p&gt;

&lt;p&gt;The system retrieves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;service lines&lt;/li&gt;
&lt;li&gt;amounts&lt;/li&gt;
&lt;li&gt;client information&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If no quote exists, the invoice can be generated directly with a free service description.&lt;/p&gt;

&lt;p&gt;Once validated, the system immediately generates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the invoice&lt;/li&gt;
&lt;li&gt;the stamped invoice (pre-generated)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The invoice is sent to the client and archived.&lt;/p&gt;

&lt;p&gt;The stamped version is stored while waiting for payment.&lt;/p&gt;




&lt;h2&gt;
  
  
  Payment confirmation
&lt;/h2&gt;

&lt;p&gt;The interface lists all pending invoices.&lt;/p&gt;

&lt;p&gt;One click is enough to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;mark the invoice as paid&lt;/li&gt;
&lt;li&gt;send the stamped invoice&lt;/li&gt;
&lt;li&gt;add the entry to the revenue journal&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The system also allows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;monthly invoice export (ZIP)&lt;/li&gt;
&lt;li&gt;monthly revenue export (CSV)&lt;/li&gt;
&lt;li&gt;annual revenue journal export&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All data is stored in simple files.&lt;/p&gt;

&lt;p&gt;No database.&lt;/p&gt;




&lt;p&gt;This system is designed to be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;autonomous&lt;/li&gt;
&lt;li&gt;installable on any PHP hosting&lt;/li&gt;
&lt;li&gt;bilingual FR / EN&lt;/li&gt;
&lt;li&gt;fully documented&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The data stays with the client.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://palks-studio.com/en/invoicing-without-saas" rel="noopener noreferrer"&gt;https://palks-studio.com/en/invoicing-without-saas&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;This is the type of systems I design at Palks Studio:&lt;/p&gt;

&lt;p&gt;simple tools that automate complete business processes.&lt;/p&gt;

&lt;p&gt;If you want to install this system on your own infrastructure:&lt;/p&gt;

&lt;p&gt;&lt;a href="mailto:contact@palks-studio.com"&gt;contact@palks-studio.com&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;If you're interested in how it works under the hood:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here’s a technical breakdown of the system architecture.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;Billing System is a suite of three interconnected billing tools accessible from a unified interface. It covers the full lifecycle of a service engagement: from quote generation to invoice settlement, including electronic signature and structured archiving.&lt;/p&gt;

&lt;p&gt;The system is designed to be deployed directly on the client's server, on a standard Apache hosting environment with PHP 8.x and Composer. It requires no database, no third-party service, and no subscription.&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;Client-side quote PDF generation (jsPDF)
&lt;/li&gt;
&lt;li&gt;Server-side invoice PDF generation (Dompdf)
&lt;/li&gt;
&lt;li&gt;Automatic pre-generation of the paid invoice at billing time
&lt;/li&gt;
&lt;li&gt;Electronic quote signing by the client (touch/mouse canvas)
&lt;/li&gt;
&lt;li&gt;Client auto-fill from archives (SIREN, SIRET, VAT, email, name)
&lt;/li&gt;
&lt;li&gt;Structured archiving by client and period
&lt;/li&gt;
&lt;li&gt;Secure sequential numbering (file lock)
&lt;/li&gt;
&lt;li&gt;Monthly export of invoices (ZIP)
&lt;/li&gt;
&lt;li&gt;Monthly export of revenue records (CSV)
&lt;/li&gt;
&lt;li&gt;Yearly export of the revenue journal (CSV)
&lt;/li&gt;
&lt;li&gt;Automatic email notifications at each stage (quote, invoice, settlement)
&lt;/li&gt;
&lt;li&gt;Cross-module navigation bar
&lt;/li&gt;
&lt;li&gt;Bilingual FR/EN interface with real-time language switch
&lt;/li&gt;
&lt;li&gt;Dark mode / light mode with persistence
&lt;/li&gt;
&lt;li&gt;No database
&lt;/li&gt;
&lt;li&gt;No SaaS dependency
&lt;/li&gt;
&lt;li&gt;Basic security: secure sessions, tokens, brute-force protection&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Project Structure
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;billing-system-en/
│
├── billing-public/
│   │  └── assets/
│   │      ├── logo*              → User logo if provided
│   │      ├── signature.png      → User signature used on quotes and invoices
│   │      ├── favicon*           → Optional site favicon displayed in the browser tab
│   │      └── jspdf.umd.min.js   → jsPDF library used to generate PDFs in the browser
│   │
│   ├── generator-direct.php      → Quote generation endpoint
│   ├── engine-direct.php         → Invoice generation endpoint
│   ├── invoice-direct.php        → Direct invoice generation endpoint
│   │
│   ├── quote-generator.php       → Web interface for quote generation
│   ├── invoice-engine.php        → Web interface for direct invoice generation
│   ├── mark-paid.php             → Web interface used to mark an invoice as paid
│   ├── signer.php                → Web interface for quote viewing and signing
│   ├── export-invoices.php       → ZIP export of archived invoices
│   ├── export-recettes.php       → CSV export of the revenue journal
│   │
│   ├── lookup.php                → Client information lookup and auto-fill
│   ├── pdf-proxy.php             → Secure PDF access via token
│   ├── .htaccess                 → Apache security and configuration rules
│   └── quote-generator-save.php  → Generated quote saving and archiving
│
├── vendor/                       → Libraries used for PDF document generation
├── templates/                    → HTML templates used to render documents
│   └── invoice-template.php      → Document rendering template (PDF or preview)
│ 
├── config.php                    → Central configuration for issuer and bank details
├── mailer.php                    → Internal email sending script with attachments
├── engine.php                    → Main engine: document generation, calculations and archiving logic
├── LICENSE.md                    → Project license
│ 
├── contracts/                    → Archive of signed and unsigned quotes
├── counters/                     → Sequential numbering counters for quotes and invoices
├── logs/                         → System logs (optional)
├── data/
│   ├── invoices/                 → Archive of invoices awaiting payment
│   ├── invoices_state/           → Pre-generated paid invoices
│   ├── invoices_paid/            → Paid invoices archive
│   └── revenues/                 → Revenue CSV files
│
└── docs/
    ├── USER_GUIDE.md             → User guide
    ├── OVERVIEW.md               → Project overview and general system description
    └── README.md                 → Usage documentation (client version)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;If you want to explore the technical implementation, you can find it here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Palks-Studio/billing-system" rel="noopener noreferrer"&gt;https://github.com/Palks-Studio/billing-system&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://palks-studio.com" rel="noopener noreferrer"&gt;https://palks-studio.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>freelance</category>
      <category>automation</category>
      <category>business</category>
      <category>backend</category>
    </item>
    <item>
      <title>You don’t need a backend to generate quotes</title>
      <dc:creator>Palks Studio</dc:creator>
      <pubDate>Sun, 08 Mar 2026 19:29:21 +0000</pubDate>
      <link>https://dev.to/palks_studio/building-a-free-quote-generator-with-no-backend-pdf-generated-in-the-browser-4f5m</link>
      <guid>https://dev.to/palks_studio/building-a-free-quote-generator-with-no-backend-pdf-generated-in-the-browser-4f5m</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvovjhusrg7jauq7mgvol.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%2Fvovjhusrg7jauq7mgvol.png" alt="Example of a generated quote (PDF output)" width="800" height="1131"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a quote should be simple.
&lt;/h2&gt;

&lt;p&gt;Yet most tools require:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;account creation
&lt;/li&gt;
&lt;li&gt;email registration
&lt;/li&gt;
&lt;li&gt;server-side storage
&lt;/li&gt;
&lt;li&gt;sometimes even a subscription.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I wanted to try a different approach.&lt;/p&gt;

&lt;p&gt;A quote generator that runs entirely in the browser.&lt;/p&gt;

&lt;p&gt;No backend.&lt;br&gt;&lt;br&gt;
No API.&lt;br&gt;&lt;br&gt;
No database.&lt;/p&gt;

&lt;p&gt;You can test it here:  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://palks-studio.com/fr/generateur-devis" rel="noopener noreferrer"&gt;https://palks-studio.com/fr/generateur-devis&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The tool generates a professional PDF quote directly in the browser without sending any data to a server.&lt;/p&gt;


&lt;h2&gt;
  
  
  Everything runs in the browser
&lt;/h2&gt;

&lt;p&gt;Everything happens client-side.&lt;/p&gt;

&lt;p&gt;User fills the form&lt;br&gt;&lt;br&gt;
↓&lt;br&gt;&lt;br&gt;
JavaScript processes the data&lt;br&gt;&lt;br&gt;
↓&lt;br&gt;&lt;br&gt;
PDF is generated locally&lt;br&gt;&lt;br&gt;
↓&lt;br&gt;&lt;br&gt;
Browser downloads the file&lt;/p&gt;

&lt;p&gt;No network request is required.&lt;/p&gt;

&lt;p&gt;The only external dependency is the jsPDF library.&lt;/p&gt;


&lt;h2&gt;
  
  
  Generating PDFs directly in JavaScript
&lt;/h2&gt;

&lt;p&gt;The generator relies on jsPDF to build the document directly in JavaScript.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once loaded, creating a PDF is straightforward.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;jsPDF&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;jspdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;doc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;jsPDF&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;unit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mm&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;a4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From there, everything can be drawn directly into the document.&lt;/p&gt;




&lt;h2&gt;
  
  
  The form mirrors the final document
&lt;/h2&gt;

&lt;p&gt;The form mirrors a real quote structure.&lt;/p&gt;

&lt;p&gt;It contains:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;issuer information
&lt;/li&gt;
&lt;li&gt;client information
&lt;/li&gt;
&lt;li&gt;quote metadata
&lt;/li&gt;
&lt;li&gt;service lines
&lt;/li&gt;
&lt;li&gt;totals
&lt;/li&gt;
&lt;li&gt;payment details&lt;/li&gt;
&lt;/ul&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card-header"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card-header-title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Your company&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card-body"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"issuer_name"&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"issuer_email"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"issuer_phone"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each section of the form maps directly to a block inside the generated PDF.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quotes need flexible line items
&lt;/h2&gt;

&lt;p&gt;Quotes require flexible service lines.&lt;/p&gt;

&lt;p&gt;Users can dynamically add or remove rows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;addLine&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="nx"&gt;lineCount&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;line-row&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;input name="lines[&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;lineCount&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;][desc]"&amp;gt;
    &amp;lt;input name="lines[&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;lineCount&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;][qty]" type="number"&amp;gt;
    &amp;lt;input name="lines[&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;lineCount&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;][price]" type="number"&amp;gt;
  `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;row&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;Each line contains:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;description
&lt;/li&gt;
&lt;li&gt;quantity
&lt;/li&gt;
&lt;li&gt;unit price
&lt;/li&gt;
&lt;li&gt;VAT rate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Totals update instantly when values change.&lt;/p&gt;




&lt;h2&gt;
  
  
  All calculations happen instantly
&lt;/h2&gt;

&lt;p&gt;All calculations are transparent and client-side.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;updateTotals&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;subtotal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;vatTotal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.line-row&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;row&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;qty&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseFloat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[name*="[qty]"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseFloat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[name*="[price]"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;vat&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseFloat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[name*="[tva]"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lineHT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;qty&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nx"&gt;subtotal&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;lineHT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;vatTotal&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;lineHT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;vat&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;subtotal&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;vatTotal&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;The UI immediately displays:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Subtotal
&lt;/li&gt;
&lt;li&gt;VAT
&lt;/li&gt;
&lt;li&gt;Total amount&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;before the PDF is generated.&lt;/p&gt;




&lt;h2&gt;
  
  
  Turning form data into a document
&lt;/h2&gt;

&lt;p&gt;When the user confirms, the script builds the document.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;jsPDF&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;jspdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;doc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;jsPDF&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;unit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mm&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;a4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then the script draws the document:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;header
&lt;/li&gt;
&lt;li&gt;issuer block
&lt;/li&gt;
&lt;li&gt;client block
&lt;/li&gt;
&lt;li&gt;service table
&lt;/li&gt;
&lt;li&gt;totals
&lt;/li&gt;
&lt;li&gt;notes
&lt;/li&gt;
&lt;li&gt;footer&lt;/li&gt;
&lt;/ul&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;QUOTE&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;quoteNumber&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;38&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every field comes directly from the form inputs.&lt;/p&gt;




&lt;h2&gt;
  
  
  Keeping the layout stable
&lt;/h2&gt;

&lt;p&gt;PDF layout can break when text becomes longer than expected.&lt;/p&gt;

&lt;p&gt;To prevent layout issues, the generator wraps text dynamically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;splitTextToSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;maxWidth&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each block calculates its own height before being drawn.&lt;/p&gt;

&lt;p&gt;This prevents overlapping elements and keeps the layout stable.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why a backend is unnecessary here
&lt;/h2&gt;

&lt;p&gt;For this type of tool, a backend is often unnecessary.&lt;/p&gt;

&lt;p&gt;Running everything in the browser provides several advantages.&lt;/p&gt;

&lt;p&gt;Privacy.&lt;/p&gt;

&lt;p&gt;No data is transmitted to any server.&lt;/p&gt;

&lt;p&gt;Simplicity.&lt;/p&gt;

&lt;p&gt;No authentication, no database, no API.&lt;/p&gt;

&lt;p&gt;Lightweight hosting.&lt;/p&gt;

&lt;p&gt;The entire generator is essentially a single HTML page.&lt;/p&gt;

&lt;p&gt;It can run on:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;static hosting
&lt;/li&gt;
&lt;li&gt;GitHub Pages
&lt;/li&gt;
&lt;li&gt;any simple web server&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What this approach does not solve
&lt;/h2&gt;

&lt;p&gt;This approach also has some limitations.&lt;/p&gt;

&lt;p&gt;There is no:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;quote history
&lt;/li&gt;
&lt;li&gt;client management
&lt;/li&gt;
&lt;li&gt;automated emailing
&lt;/li&gt;
&lt;li&gt;electronic signature workflow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But for generating quick quotes, it works extremely well.&lt;/p&gt;




&lt;h2&gt;
  
  
  What this tool is designed for
&lt;/h2&gt;

&lt;p&gt;The goal was not to build a SaaS product.&lt;/p&gt;

&lt;p&gt;The goal was to build a tool that is:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;simple
&lt;/li&gt;
&lt;li&gt;frictionless
&lt;/li&gt;
&lt;li&gt;immediately usable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No login.&lt;/p&gt;

&lt;p&gt;No tracking.&lt;/p&gt;

&lt;p&gt;No data collection.&lt;/p&gt;

&lt;p&gt;Just a form and a downloadable PDF.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try it yourself
&lt;/h2&gt;

&lt;p&gt;You can test it here:  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://palks-studio.com/fr/generateur-devis" rel="noopener noreferrer"&gt;https://palks-studio.com/fr/generateur-devis&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It works on:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;desktop
&lt;/li&gt;
&lt;li&gt;mobile
&lt;/li&gt;
&lt;li&gt;any modern browser&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Sometimes simpler is better
&lt;/h2&gt;

&lt;p&gt;Modern web tools often become unnecessarily complex.&lt;/p&gt;

&lt;p&gt;For some use cases, a simple client-side application is more than enough.&lt;/p&gt;

&lt;p&gt;A single HTML file with JavaScript can already provide:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a structured form
&lt;/li&gt;
&lt;li&gt;dynamic calculations
&lt;/li&gt;
&lt;li&gt;professional PDF generation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sometimes simplicity is the best solution.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Palks-Studio/free-quote-generator" rel="noopener noreferrer"&gt;https://github.com/Palks-Studio/free-quote-generator&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://palks-studio.com" rel="noopener noreferrer"&gt;https://palks-studio.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>opensource</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Generating Factur-X is easy. Making it valid is not.</title>
      <dc:creator>Palks Studio</dc:creator>
      <pubDate>Wed, 04 Mar 2026 21:46:31 +0000</pubDate>
      <link>https://dev.to/palks_studio/building-a-factur-x-en16931-engine-from-scratch-what-actually-took-time-2bg2</link>
      <guid>https://dev.to/palks_studio/building-a-factur-x-en16931-engine-from-scratch-what-actually-took-time-2bg2</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzjpskobf9dvo6uqhd2as.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%2Fzjpskobf9dvo6uqhd2as.png" alt="Factur-X EN16931 pipeline — structured invoicing engine" width="800" height="1131"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When I started working on B2B e-invoicing, I thought the technical part would be straightforward. Generate a PDF, embed an XML, follow a standard. On paper, it seemed linear.&lt;/p&gt;

&lt;p&gt;In practice, it's something else entirely.&lt;/p&gt;

&lt;p&gt;Here's what actually took time — not the concepts, but the details that break everything in production.&lt;/p&gt;

&lt;p&gt;The Comfort profile is not declared — it is earned&lt;/p&gt;

&lt;p&gt;EN16931 defines several profiles. The Comfort profile, the one that guarantees real interoperability with accounting systems, requires strict identifier completeness.&lt;/p&gt;

&lt;p&gt;SIREN alone is not enough. SIRET alone is not enough. The combination of SIREN + SIRET + VAT number determines the profile declared in the XML. If one identifier is missing, the profile changes. And an incorrect profile means a technically invalid invoice — even if it looks perfectly fine visually.&lt;/p&gt;

&lt;p&gt;I implemented conditional validation logic before generation. No silent correction, no approximation. Either the data is complete, or the invoice does not go out.&lt;/p&gt;

&lt;p&gt;Multi-period invoicing is a state problem, not a calculation problem&lt;/p&gt;

&lt;p&gt;Invoicing across multiple months in a single document seems simple. It is not.&lt;/p&gt;

&lt;p&gt;The real issue: a period included in an issued invoice is permanently closed. It cannot be re-invoiced, partially modified, or cancelled. This is not a software constraint — it is a legal and accounting one.&lt;/p&gt;

&lt;p&gt;I had to model an explicit state system per period and per client, using immutable archiving flags. No database — only locked, deterministic and traceable files.&lt;/p&gt;

&lt;p&gt;Deduplication without a database&lt;/p&gt;

&lt;p&gt;The classic question: how do you prevent issuing the same invoice twice if the process is restarted?&lt;/p&gt;

&lt;p&gt;My answer: file-based locks. Each execution cycle checks for the existence of a lock file before generating anything. No race condition, no distributed transaction, no external dependency. One execution = one deterministic cycle. If the file exists, skip. Otherwise, generate and lock.&lt;/p&gt;

&lt;p&gt;Simple, traceable, reliable.&lt;/p&gt;

&lt;p&gt;The pipeline runs on cron — no background process, no service to keep alive&lt;/p&gt;

&lt;p&gt;No persistent process running in the background, no service to maintain active, no SaaS dependency. The engine triggers, processes, archives and stops. Each execution is independent and reproducible.&lt;/p&gt;

&lt;p&gt;This architectural choice has a direct consequence: if something goes wrong, there is nothing to restart, nothing to debug live. Logs are exhaustive, states are explicit, generated files are evidence.&lt;/p&gt;

&lt;p&gt;What I take from this&lt;/p&gt;

&lt;p&gt;Factur-X is not a PDF generation problem. It is a structured pipeline problem — controlled states and normalized data before production.&lt;br&gt;
Tools that "generate Factur-X" are plentiful. Systems that guarantee end-to-end compliance, full traceability and zero implicit correction are far less common.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://palks-studio.com/en/batch-invoicing-facturx" rel="noopener noreferrer"&gt;https://palks-studio.com/en/batch-invoicing-facturx&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;If you're interested in how it works under the hood:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here’s a technical breakdown of the system architecture.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Overview Project
&lt;/h2&gt;

&lt;p&gt;This repository presents a financial automation system designed to handle:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;invoice generation (single &amp;amp; batch)
&lt;/li&gt;
&lt;li&gt;revenue tracking
&lt;/li&gt;
&lt;li&gt;payment reconciliation
&lt;/li&gt;
&lt;li&gt;client balances
&lt;/li&gt;
&lt;li&gt;accounting-ready exports&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The system is deterministic, auditable, and explicit by design.&lt;/p&gt;

&lt;p&gt;It operates:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;without a database
&lt;/li&gt;
&lt;li&gt;without a CMS
&lt;/li&gt;
&lt;li&gt;without a SaaS dependency
&lt;/li&gt;
&lt;li&gt;without any exposed web interface&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All executions run server-side, via CLI scripts and cron, with a strict separation of responsibilities.&lt;/p&gt;

&lt;p&gt;This project is not a product, not a SaaS, and not a plug-and-play tool.&lt;br&gt;&lt;br&gt;
It documents a production-grade approach to financial automation.&lt;/p&gt;

&lt;p&gt;Over time, the engine has been progressively extended&lt;br&gt;&lt;br&gt;
to cover real-world business cases,&lt;br&gt;&lt;br&gt;
without compromising its original design principles.&lt;/p&gt;

&lt;p&gt;The billing system now supports:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;multi-line invoices
&lt;/li&gt;
&lt;li&gt;multiple VAT rates per invoice
&lt;/li&gt;
&lt;li&gt;complex or extended service periods
&lt;/li&gt;
&lt;li&gt;multi-month billing scenarios
&lt;/li&gt;
&lt;li&gt;complex combinations while remaining EN16931 Comfort compliant&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This functional expansion did not alter&lt;br&gt;&lt;br&gt;
the deterministic, auditable, and traceable nature of the system.&lt;/p&gt;

&lt;h3&gt;
  
  
  Electronic invoicing (Factur-X)
&lt;/h3&gt;

&lt;p&gt;The system natively integrates Factur-X electronic invoicing (hybrid PDF with embedded XML),&lt;br&gt;&lt;br&gt;
in compliance with the European EN 16931 standard (Comfort profile):  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;generation of a semantically EN 16931-compliant Factur-X XML
&lt;/li&gt;
&lt;li&gt;XML validation (XSD and Schematron)
&lt;/li&gt;
&lt;li&gt;injection of the XML into the PDF
&lt;/li&gt;
&lt;li&gt;production of a single final document: the Factur-X hybrid PDF
&lt;/li&gt;
&lt;li&gt;direct integration into the &lt;code&gt;run.php&lt;/code&gt; and &lt;code&gt;run_batch.php&lt;/code&gt; pipelines
&lt;/li&gt;
&lt;li&gt;no parallel formats
&lt;/li&gt;
&lt;li&gt;no persistent XML storage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The system targets business compliance and e-invoicing interoperability (France / EU).&lt;br&gt;&lt;br&gt;
PDF/A compliance (document archiving) is not a functional objective of the project and is deliberately out of scope.&lt;/p&gt;

&lt;p&gt;Factur-X is handled as a native component of the engine,&lt;br&gt;&lt;br&gt;
not as an external or optional module.&lt;/p&gt;




&lt;h2&gt;
  
  
  Project structure
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;automation_finance/
│
├── engine/
│   ├── build_facturx_xml.php         → Factur-X XML generation
│   ├── build_json.php                → Client onboarding JSON builder
│   ├── inject_facturx.py             → Factur-X XML injection into PDF
│   ├── run.php                       → Main automation engine (cron / CLI)
│   ├── run_batch.php                 → Batch automation engine for client invoicing
│   ├── billing_rules.php             → Billing rules and dynamic pricing logic
│   ├── alerts.php                    → Execution alerts and notifications handling
│   ├── import_csv.php                → Client CSV import and validation handler
│   ├── mailer.php                    → Email sender with invoice attachment
│   ├── mail_signature.php            → Palks Studio signature
│   ├── vendor/                       → PHP dependencies (e.g. DomPDF)
│   └── templates/                    → Invoices PDF template (bilingual FR / EN)
│
├── data/
│   ├── logs/                         → Execution logs per client
│   ├── onboarding/                   → JSON files generated by the client onboarding form
│   ├── onboarding_done/              → Processed onboarding JSON archived after build
│   ├── archive_batch/                → Archived client CSV
│   ├── batch_sent/                   → Zip sent
│   ├── usage/                        → Monthly client usage tracking
│   ├── revenues/                     → Cumulative revenues (internal accounting source)
│   ├── payments/                     → Payments received from the client (bank transfers, actually received amounts)
│   ├── balance/                      → Client accounting balance (invoiced vs paid, paid / unpaid status)
│   ├── invoices/                     → Invoices from the main activity (direct invoicing, internal use)
│   ├── invoices_batch/               → Invoices generated as part of the batch service (end clients)
│   ├── inbox_batch/                  → Client-provided CSV file (batch invoicing source)
│   ├── counters/                     → Annual invoice counter per client (direct invoicing)
│   └── counters_batch/               → Annual invoice counter per client (batch invoicing)
│
├── tools/
│   ├── update_balances.php           → Updates client balances based on revenues and payments
│   ├── find_client.php               → Client lookup utility
│   ├── build_client.php              → Client email index builder
│   ├── send_paid_receipts.php        → Automatic sending of paid client receipts
│   ├── purge_log.php                 → Cleanup Script
│   ├── client_project.php            → CLI script aggregating and exporting client data by identifier
│   ├── recettes_year.php             → Export actually received revenues for a full year
│   ├── recettes_month.php            → Export actually received revenues for a given month
│   └── revenues_csv.php              → Export revenues to a CSV file (accounting)
│
├── exports/
│   ├── recettes/                     → Monthly CSV exports generated on demand / Yearly CSV exports generated on demand
│   └── payments/                     → CSV generated from the received payments JSON files
│
├── downloads/                        → Monthly ZIP archives per client, containing automatically generated PDF invoices
├── clients/                          → Client configuration file (only file to edit per client)
├── batch_clients/                    → Batch configuration for an end client (monthly invoicing)
├── CONTRATS/                         → Legal documents related to the service
│
├── LICENCE.md                        → Conditions d’utilisation et cadre légal (FR)
├── LICENSE.md                        → Terms of use and legal Framework
│
└── docs/
    ├── README_FR.md                  → Documentation générale du système (FR)
    ├── README.md                     → General system documentation
    │
    ├── SERVICE_MEMO_FR.md            → Note interne de positionnement du service (FR)
    ├── SERVICE_MEMO.md               → Internal Service Positioning Memo
    │
    ├── README_DEPLOY_FR.md           → Guide d’installation et d’exploitation (FR)
    ├── README_DEPLOY_EN.md           → Installation and Production Guide
    │
    ├── VUE_DENSEMBLE_AUTOMATION.md   → Vue d’ensemble du système d’automatisation de facturation (FR)
    └── SYSTEM_OVERVIEW_AUTOMATION.md → Billing Automation System Overview
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;If you want to explore the technical implementation, you can find it here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Palks-Studio/automation-finance" rel="noopener noreferrer"&gt;https://github.com/Palks-Studio/automation-finance&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://palks-studio.com" rel="noopener noreferrer"&gt;https://palks-studio.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>backend</category>
      <category>payments</category>
      <category>php</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Your e-invoicing stack isn’t broken — your architecture is</title>
      <dc:creator>Palks Studio</dc:creator>
      <pubDate>Fri, 27 Feb 2026 16:57:58 +0000</pubDate>
      <link>https://dev.to/palks_studio/e-invoicing-is-not-a-tooling-problem-12oj</link>
      <guid>https://dev.to/palks_studio/e-invoicing-is-not-a-tooling-problem-12oj</guid>
      <description>&lt;h2&gt;
  
  
  It is an architecture problem.
&lt;/h2&gt;

&lt;p&gt;For months, e-invoicing has been discussed as if it were just another digital upgrade.&lt;/p&gt;

&lt;p&gt;As if the topic could be reduced to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;switching software&lt;/li&gt;
&lt;li&gt;converting PDFs&lt;/li&gt;
&lt;li&gt;automating documents&lt;/li&gt;
&lt;li&gt;plugging in a new tool&lt;/li&gt;
&lt;li&gt;adding a technical component&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This reading is misleading.&lt;/p&gt;

&lt;p&gt;E-invoicing is not a format modernization.&lt;br&gt;
It is a structural shift.&lt;/p&gt;




&lt;h2&gt;
  
  
  What many people assume
&lt;/h2&gt;

&lt;p&gt;Today, many organizations approach e-invoicing as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a software issue&lt;/li&gt;
&lt;li&gt;a tooling issue&lt;/li&gt;
&lt;li&gt;an automation issue&lt;/li&gt;
&lt;li&gt;a conversion issue&lt;/li&gt;
&lt;li&gt;a digitization issue&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So they keep stacking:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PDFs&lt;/li&gt;
&lt;li&gt;tools&lt;/li&gt;
&lt;li&gt;connectors&lt;/li&gt;
&lt;li&gt;platforms&lt;/li&gt;
&lt;li&gt;automations&lt;/li&gt;
&lt;li&gt;scripts&lt;/li&gt;
&lt;li&gt;third-party services&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…without ever addressing the core problem.&lt;/p&gt;




&lt;h2&gt;
  
  
  The real issue
&lt;/h2&gt;

&lt;p&gt;An e-invoice is not a digital document.&lt;br&gt;
It is a structured object.&lt;/p&gt;

&lt;p&gt;It contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a human-readable PDF&lt;/li&gt;
&lt;li&gt;a machine-readable XML structure&lt;/li&gt;
&lt;li&gt;a European standard (EN16931)&lt;/li&gt;
&lt;li&gt;strict semantic rules&lt;/li&gt;
&lt;li&gt;machine interoperability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not just a file.&lt;br&gt;
It is normalized data.&lt;/p&gt;




&lt;h2&gt;
  
  
  Where systems break
&lt;/h2&gt;

&lt;p&gt;Today, many “solutions” still produce:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;unstructured PDFs&lt;/li&gt;
&lt;li&gt;non-exploitable conversions&lt;/li&gt;
&lt;li&gt;heterogeneous formats&lt;/li&gt;
&lt;li&gt;inconsistent flows&lt;/li&gt;
&lt;li&gt;non-standardized data&lt;/li&gt;
&lt;li&gt;manual reprocessing&lt;/li&gt;
&lt;li&gt;dependencies on third-party tools&lt;/li&gt;
&lt;li&gt;invisible operational debt&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not digital transformation.&lt;br&gt;
It is structural debt.&lt;/p&gt;




&lt;h2&gt;
  
  
  Automation is not the problem
&lt;/h2&gt;

&lt;p&gt;Automation is not the enemy.&lt;br&gt;
Tools are not the enemy.&lt;br&gt;
Platforms are not the enemy.&lt;br&gt;
AI is not the enemy.&lt;/p&gt;

&lt;p&gt;The problem is the order of operations.&lt;/p&gt;

&lt;p&gt;When you automate poorly structured data,&lt;br&gt;
you don’t create performance —&lt;br&gt;
you industrialize disorder.&lt;/p&gt;




&lt;h2&gt;
  
  
  The business reality
&lt;/h2&gt;

&lt;p&gt;E-invoicing requires:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;structured flows&lt;/li&gt;
&lt;li&gt;normalized data&lt;/li&gt;
&lt;li&gt;format consistency&lt;/li&gt;
&lt;li&gt;processing traceability&lt;/li&gt;
&lt;li&gt;pipeline readability&lt;/li&gt;
&lt;li&gt;architectural thinking&lt;/li&gt;
&lt;li&gt;system continuity&lt;/li&gt;
&lt;li&gt;process stability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not a software project.&lt;br&gt;
It is a data architecture project.&lt;/p&gt;




&lt;h2&gt;
  
  
  Tool vs system
&lt;/h2&gt;

&lt;p&gt;A tool:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;executes&lt;/li&gt;
&lt;li&gt;produces&lt;/li&gt;
&lt;li&gt;automates&lt;/li&gt;
&lt;li&gt;transforms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;structures&lt;/li&gt;
&lt;li&gt;controls&lt;/li&gt;
&lt;li&gt;validates&lt;/li&gt;
&lt;li&gt;secures&lt;/li&gt;
&lt;li&gt;guarantees&lt;/li&gt;
&lt;li&gt;traces&lt;/li&gt;
&lt;li&gt;normalizes&lt;/li&gt;
&lt;li&gt;organizes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tools do the work.&lt;br&gt;
Systems make it reliable.&lt;/p&gt;




&lt;h2&gt;
  
  
  What e-invoicing actually changes
&lt;/h2&gt;

&lt;p&gt;It transforms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;how data is produced&lt;/li&gt;
&lt;li&gt;how flows are designed&lt;/li&gt;
&lt;li&gt;how information circulates&lt;/li&gt;
&lt;li&gt;how systems communicate&lt;/li&gt;
&lt;li&gt;how companies interoperate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not an interface change.&lt;br&gt;
It is a logic shift.&lt;/p&gt;




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

&lt;p&gt;E-invoicing is not:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a tool&lt;/li&gt;
&lt;li&gt;a software product&lt;/li&gt;
&lt;li&gt;an API&lt;/li&gt;
&lt;li&gt;a platform&lt;/li&gt;
&lt;li&gt;an automation layer&lt;/li&gt;
&lt;li&gt;a connector&lt;/li&gt;
&lt;li&gt;an improved PDF format&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is an architecture.&lt;/p&gt;

&lt;p&gt;Those who treat it as simple document conversion will build fragile systems.&lt;br&gt;
Those who treat it as a structural problem will build durable ones.&lt;/p&gt;




&lt;h2&gt;
  
  
  At Palks Studio, our approach is simple
&lt;/h2&gt;

&lt;p&gt;We don’t patch things after generation.&lt;br&gt;
We structure before production.&lt;/p&gt;

&lt;p&gt;Because compliance is not something you fix.&lt;br&gt;
It is something you build.&lt;/p&gt;

&lt;p&gt;Because reliability is not something you add.&lt;br&gt;
It is something you design.&lt;/p&gt;

&lt;p&gt;Because interoperability is not something you enable.&lt;br&gt;
It is something you organize.&lt;/p&gt;




&lt;p&gt;E-invoicing is not a digital transformation.&lt;br&gt;
It is a structural transformation.&lt;/p&gt;

&lt;p&gt;And in the end, systems will last.&lt;br&gt;
Not hype.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://palks-studio.com" rel="noopener noreferrer"&gt;https://palks-studio.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>payments</category>
      <category>backend</category>
      <category>software</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Most SaaS tools create noise. I built my own assistant instead.</title>
      <dc:creator>Palks Studio</dc:creator>
      <pubDate>Wed, 18 Feb 2026 18:14:45 +0000</pubDate>
      <link>https://dev.to/palks_studio/building-a-local-personal-assistant-instead-of-using-saas-tools-3fpn</link>
      <guid>https://dev.to/palks_studio/building-a-local-personal-assistant-instead-of-using-saas-tools-3fpn</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft21h5qg0h8rvb76z0e43.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%2Ft21h5qg0h8rvb76z0e43.png" alt="Jason personal assistant running three independent conversations locally" width="800" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a Local Personal Assistant Instead of Using SaaS Tools
&lt;/h2&gt;

&lt;p&gt;Most developers use dozens of tools every day.&lt;/p&gt;

&lt;p&gt;Notes apps, documentation tools, AI assistants, reminders, knowledge bases…&lt;br&gt;
Everything lives somewhere else, often online, often fragmented.&lt;/p&gt;

&lt;p&gt;At some point, I realized the problem wasn’t missing tools.&lt;br&gt;
It was the lack of structure.&lt;/p&gt;

&lt;p&gt;So I built my own personal assistant.&lt;/p&gt;

&lt;p&gt;Not as an AI experiment.&lt;br&gt;
Not as a product.&lt;br&gt;
Just as a tool I could rely on every day.&lt;/p&gt;




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

&lt;p&gt;When working on multiple projects, information tends to mix:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;project summaries&lt;/li&gt;
&lt;li&gt;technical details&lt;/li&gt;
&lt;li&gt;quick notes&lt;/li&gt;
&lt;li&gt;meetings and reminders&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Traditional assistants try to merge everything into a single conversation.&lt;br&gt;
That sounds convenient, but in practice it creates noise.&lt;/p&gt;

&lt;p&gt;The same keyword can mean different things depending on context.&lt;/p&gt;

&lt;p&gt;I needed separation instead of intelligence.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Idea: One Role Per Window
&lt;/h2&gt;

&lt;p&gt;My assistant, called Jason, is based on a simple idea:&lt;/p&gt;

&lt;p&gt;one window = one role.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Overview → project summaries&lt;/li&gt;
&lt;li&gt;Technical → internal details and configuration&lt;/li&gt;
&lt;li&gt;Memory → quick notes, meetings, reminders&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each conversation has its own history.&lt;br&gt;
No cross-context interference.&lt;br&gt;
No confusion.&lt;/p&gt;

&lt;p&gt;The goal is predictability.&lt;/p&gt;




&lt;h2&gt;
  
  
  Local First
&lt;/h2&gt;

&lt;p&gt;The assistant runs locally.&lt;/p&gt;

&lt;p&gt;The knowledge base is just files.&lt;br&gt;
Readable, editable, versionable.&lt;/p&gt;

&lt;p&gt;No external platform.&lt;br&gt;
No vendor lock-in.&lt;br&gt;
No hidden behavior.&lt;/p&gt;

&lt;p&gt;Internet is optional.&lt;/p&gt;

&lt;p&gt;This keeps the system fast and under control.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Not Use Existing Tools?
&lt;/h2&gt;

&lt;p&gt;Because most tools optimize for features.&lt;/p&gt;

&lt;p&gt;I wanted something optimized for clarity.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no automatic restructuring&lt;/li&gt;
&lt;li&gt;no unexpected behavior&lt;/li&gt;
&lt;li&gt;no dependency on external services&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Just a reliable assistant that reflects how I actually work.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Result
&lt;/h2&gt;

&lt;p&gt;Jason starts with my system and stays available in the background.&lt;/p&gt;

&lt;p&gt;It can answer multiple conversations at the same time,&lt;br&gt;
each with a different purpose.&lt;/p&gt;

&lt;p&gt;It’s not impressive from a marketing perspective.&lt;br&gt;
But it’s extremely useful in daily work.&lt;/p&gt;

&lt;p&gt;And that’s the point.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;Sometimes the best developer tools are not the most powerful ones.&lt;/p&gt;

&lt;p&gt;They’re the ones that remove friction.&lt;/p&gt;




&lt;p&gt;This is the kind of tooling I build for my own workflow at Palks Studio.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://palks-studio.com" rel="noopener noreferrer"&gt;https://palks-studio.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>tooling</category>
      <category>productivity</category>
      <category>python</category>
      <category>flask</category>
    </item>
    <item>
      <title>If your editor changes your code without asking, it’s broken</title>
      <dc:creator>Palks Studio</dc:creator>
      <pubDate>Sat, 14 Feb 2026 15:39:40 +0000</pubDate>
      <link>https://dev.to/palks_studio/why-i-stopped-over-customizing-my-vs-code-setup-374a</link>
      <guid>https://dev.to/palks_studio/why-i-stopped-over-customizing-my-vs-code-setup-374a</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F701aa6uop3f47q8vk1l8.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%2F701aa6uop3f47q8vk1l8.png" alt="VS Code environment pack before and after configuration comparison" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For years, my VS Code environment kept getting more complex.&lt;/p&gt;

&lt;p&gt;More extensions, more automation, more tools supposed to make development easier.&lt;br&gt;&lt;br&gt;
On paper, everything looked efficient. In practice, I spent more and more time fixing side effects.&lt;/p&gt;

&lt;p&gt;Files reformatted themselves on save.&lt;br&gt;&lt;br&gt;
Indentation changed unexpectedly.&lt;br&gt;&lt;br&gt;
Two projects could look different simply because an extension behaved differently.&lt;/p&gt;

&lt;p&gt;The tools were supposed to help.&lt;/p&gt;

&lt;p&gt;Instead, they took control away.&lt;/p&gt;




&lt;h2&gt;
  
  
  The problem with automatic tooling
&lt;/h2&gt;

&lt;p&gt;Automatic formatting is convenient — until it stops being predictable.&lt;/p&gt;

&lt;p&gt;Some extensions rewrite code structure without real context.&lt;br&gt;&lt;br&gt;
Others apply different rules depending on language or local configuration.&lt;/p&gt;

&lt;p&gt;Nothing is necessarily wrong, but the environment becomes unstable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;invisible changes appear in commits&lt;/li&gt;
&lt;li&gt;code readability changes between projects&lt;/li&gt;
&lt;li&gt;and it becomes harder to understand what actually changed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At some point, I realized I was spending more time supervising my editor than writing code.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I actually wanted
&lt;/h2&gt;

&lt;p&gt;I didn’t want more automation.&lt;/p&gt;

&lt;p&gt;I wanted fewer surprises.&lt;/p&gt;

&lt;p&gt;A simple and predictable environment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no automatic changes without intent&lt;/li&gt;
&lt;li&gt;consistent rendering across projects&lt;/li&gt;
&lt;li&gt;formatting executed only when necessary&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal was not to make the editor smarter,&lt;br&gt;
but to make it more reliable.&lt;/p&gt;




&lt;h2&gt;
  
  
  Moving back to control instead of automation
&lt;/h2&gt;

&lt;p&gt;I gradually removed everything that modified code automatically.&lt;/p&gt;

&lt;p&gt;No format-on-save.&lt;br&gt;&lt;br&gt;
No extensions rewriting files in the background.&lt;br&gt;&lt;br&gt;
No hidden actions.&lt;/p&gt;

&lt;p&gt;Instead, I adopted a simpler approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;cleanup actions are manual&lt;/li&gt;
&lt;li&gt;scripts run locally&lt;/li&gt;
&lt;li&gt;every modification is intentional&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The code is never modified unless I explicitly decide to do it.&lt;/p&gt;

&lt;p&gt;At first this feels less modern, but it has an immediate benefit:&lt;br&gt;
everything becomes predictable again.&lt;/p&gt;




&lt;h2&gt;
  
  
  What changed in practice
&lt;/h2&gt;

&lt;p&gt;The biggest change wasn’t technical — it was mental.&lt;/p&gt;

&lt;p&gt;Less friction.&lt;br&gt;&lt;br&gt;
Fewer broken files caused by unexpected formatting.&lt;br&gt;&lt;br&gt;
A more stable and readable codebase over time.&lt;/p&gt;

&lt;p&gt;My editor stopped making decisions for me.&lt;br&gt;
It became a tool again.&lt;/p&gt;

&lt;p&gt;All my projects started behaving the same way, regardless of system or context.&lt;/p&gt;




&lt;h2&gt;
  
  
  Local backups changed how I work
&lt;/h2&gt;

&lt;p&gt;Another important change was how I handled file safety.&lt;/p&gt;

&lt;p&gt;Instead of relying on extensions or external tools, I added a simple local backup system: every time a file is saved, a timestamped copy is created locally.&lt;/p&gt;

&lt;p&gt;It’s not complex, but it removes unnecessary stress.&lt;br&gt;&lt;br&gt;
A file can be modified, broken, or even deleted by mistake — a previous version still exists.&lt;/p&gt;

&lt;p&gt;This kind of local safety changes the way you work.&lt;br&gt;&lt;br&gt;
You experiment more freely because losing a stable version of your code becomes much less likely.&lt;/p&gt;




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

&lt;p&gt;Over time, this setup became reusable because I wanted the same stability across projects.&lt;/p&gt;

&lt;p&gt;But the real change wasn’t the configuration itself.&lt;/p&gt;

&lt;p&gt;It was the mindset behind it:&lt;/p&gt;

&lt;p&gt;tools should never modify code without intent.&lt;/p&gt;

&lt;p&gt;Eventually, this environment evolved into a reusable setup at Palks Studio, but the main benefit remains the same — clarity, control, and predictability.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://palks-studio.com/en/vscode-environment-pack" rel="noopener noreferrer"&gt;https://palks-studio.com/en/vscode-environment-pack&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;If you're interested in how it works under the hood:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here’s a technical breakdown of the system architecture.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  VS Code – Environment Pack
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;configured working environment&lt;/strong&gt; for Visual Studio Code.&lt;/p&gt;

&lt;p&gt;This pack provides a clear and consistent framework for formatting, cleanup, and normalization&lt;br&gt;&lt;br&gt;
of common file types (&lt;code&gt;.py&lt;/code&gt;, &lt;code&gt;.html&lt;/code&gt;, &lt;code&gt;.css&lt;/code&gt;, &lt;code&gt;.js&lt;/code&gt;, &lt;code&gt;.json&lt;/code&gt;, &lt;code&gt;.txt&lt;/code&gt;),&lt;br&gt;&lt;br&gt;
using VS Code settings and locally executed Python scripts.&lt;/p&gt;

&lt;p&gt;The goal is not blind automation,&lt;br&gt;&lt;br&gt;
but a &lt;strong&gt;controlled set of tools&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
that lets you keep full control over code structure, readability, and consistency,&lt;br&gt;&lt;br&gt;
regardless of the operating system.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why this environment exists
&lt;/h2&gt;

&lt;p&gt;Most editors automatically reformat code when saving files.&lt;br&gt;&lt;br&gt;
While convenient, this can introduce unexpected changes,&lt;br&gt;&lt;br&gt;
inconsistent formatting, or conflicts between extensions.&lt;/p&gt;

&lt;p&gt;This pack takes the opposite approach:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no automatic formatting
&lt;/li&gt;
&lt;li&gt;no hidden actions
&lt;/li&gt;
&lt;li&gt;manual tools executed only when needed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is to keep code stable, readable and predictable,&lt;br&gt;&lt;br&gt;
while giving full control to the developer.&lt;/p&gt;




&lt;h2&gt;
  
  
  Pack Structure
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vscode_environment_pack_v1.1/
│
├── .vscode/
│   ├── extensions.json                 → Local disabling of conflicting extensions (Prettier, RunOnSave)
│   ├── launch.json                     → Quick execution of the active Python script
│   ├── settings.json                   → Complete VS Code settings (indentation, LF, UTF-8, editor comfort)
│   ├── keybindings.json                → Shortcuts: Alt + M (minimap), Alt + R (re-indentation)
│   └── tasks.json                      → VS Code tasks (manually executable):
│                                           - Python Formatting + Margin Cleanup
│                                             (autopep8 + clean.py, active file)
│                                           - Margin Cleanup (clean.py — global / active file / custom selection)
│                                           - Margin Detection (space.py — read-only analysis)
│                                           - CRLF → LF Conversion (convert.py — global / active file / custom selection)
│
├── clean.py                            → General margin and whitespace cleanup
├── convert.py                          → Line ending normalization (CRLF → LF)
├── space.py                            → Margin analysis (read-only)
├── backup.py                           → Timestamped backup of the file on save (Ctrl + S)
│                                         via the Auto-Backup task
│ 
├── LICENSE.md                          → Terms of use and legal framework
│ 
└── docs/
    ├── TECHNICAL_README.md             → Technical documentation and internal structure
    ├── README_COMMERCIAL.md            → Project overview and public presentation
    ├── INSTALL.md                      → Installation and usage guide
    │
    └── examples/
        ├── before.py                   → Dirty / unstructured example files
        ├── after.py                    → Clean, formatted versions generated by the pack
        ├── convert_lf.mp4              → CRLF files automatically converted to LF
        ├── indent_clean.mp4            → Broken indentation/margins fixed instantly
        ├── indent_python.mp4           → Badly indented Python file auto-corrected
        ├── backup.mp4                  → Demonstrates automatic file backup on each save (Ctrl + S)
        │                                 and how to restore a deleted file from the backup folder
        └── space_clean.mp4             → Broken file analyzed and margins detected (read-only)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;If you want to explore the technical implementation, you can find it here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Palks-Studio/vs-code-environment-pack" rel="noopener noreferrer"&gt;https://github.com/Palks-Studio/vs-code-environment-pack&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://palks-studio.com" rel="noopener noreferrer"&gt;https://palks-studio.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vscode</category>
      <category>productivity</category>
      <category>tooling</category>
      <category>development</category>
    </item>
  </channel>
</rss>
