<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Antonio Fullone Blog RSS Feed]]></title><description><![CDATA[Personal Website of Antonio Fullone, Designer &amp; Developer]]></description><link>https://www.antoniofullone.com</link><generator>GatsbyJS</generator><lastBuildDate>Sun, 10 May 2026 19:07:54 GMT</lastBuildDate><item><title><![CDATA[The pillars of a painkiller AI app]]></title><description><![CDATA[Everyone is building apps today. It has never been so easy. Just learn some prompting and that's it, right? Sure — until your (most likely…]]></description><link>https://www.antoniofullone.com/blog/the-pillars-of-a-painkiller-ai-app</link><guid isPermaLink="false">https://www.antoniofullone.com/blog/the-pillars-of-a-painkiller-ai-app</guid><pubDate>Thu, 30 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Everyone is building apps today. It has never been so easy. Just learn some prompting and that&apos;s it, right? Sure — until your (most likely wrapper) AI app becomes a feature inside one of the giants. It has happened. It will keep happening.&lt;/p&gt;
&lt;p&gt;There&apos;s a name for this: &lt;a href=&quot;https://thehustle.co/sherlocking-explained&quot;&gt;getting Sherlocked&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Your AI app needs to be a painkiller, not a vitamin. Nice-to-haves get Sherlocked. Need-to-haves get paid.&lt;/p&gt;
&lt;p&gt;But how do you build a painkiller? I&apos;ve been building for a while now, and here is what I&apos;ve learned that separates the apps clients can&apos;t live without from the ones they forget by Friday.&lt;/p&gt;
&lt;h2&gt;Fix the friction &lt;em&gt;nobody defends&lt;/em&gt;&lt;/h2&gt;
&lt;p&gt;The instinct is to automate the impressive work. The real opportunity is to automate the work nobody is proud of doing.&lt;/p&gt;
&lt;p&gt;Imagine a young intern starts at a law firm. They&apos;re smart, they use AI, and they build a workflow that reads incoming client emails, analyzes the request, and prepares a brief for the lawyer. It looks great on paper. It saves hours.&lt;/p&gt;
&lt;p&gt;Then they show it to the lawyer.&lt;/p&gt;
&lt;p&gt;First problem: privacy. A law firm cannot let client data flow through a third-party model. Second problem: what happens when the AI hallucinates? Isn&apos;t it safer to let the senior secretary, who has been doing this for fifteen years, handle it? Third problem, the one nobody says out loud: the lawyer bills by the hour. Saving them time on the work they bill for is saving them revenue.&lt;/p&gt;
&lt;p&gt;The intern goes back to their desk. They watch their colleagues work. They notice everyone wastes ten minutes a day searching for documents because the shared drive is chaos. Files named &lt;code&gt;final_v2_REAL_final.docx&lt;/code&gt;, folders nobody owns, no tagging system. People complain about it constantly. Nobody fixes it because nobody is paid to fix it.&lt;/p&gt;
&lt;p&gt;The intern builds an automation that organizes files by tags, names, and dates. Now we&apos;re talking. No client data leaves the building. No expert is being replaced. No billable hour is being eliminated. Just a frustration everybody had and nobody wanted to own.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;That&apos;s the shape of a painkiller.
Not the workflow people are proud of, but the friction nobody defends.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Context is &lt;em&gt;not what you think&lt;/em&gt;&lt;/h2&gt;
&lt;p&gt;You think context means feeding more data to the AI, right? Dump the document in, get a smart answer out. That&apos;s not how it works.&lt;/p&gt;
&lt;p&gt;We all know AI can hallucinate. But that&apos;s not the real problem. The real problem is more interesting.&lt;/p&gt;
&lt;p&gt;You get your blood test back from the clinic. You upload the PDF to ChatGPT or Claude. The model has real data — actual numbers, not abstract symptoms. It gives you a confident answer. Maybe asks a clarifying question or two.&lt;/p&gt;
&lt;p&gt;But the AI doesn&apos;t know if you smoke. If you drink. If your father had a heart attack at 50. If you&apos;ve been on a cutting diet for three months or eating takeout for ten years. If you go to the gym or sit on the couch watching Netflix. The data on the page is real, but its meaning depends entirely on who you are. Same numbers, two different people, two different diagnoses.&lt;/p&gt;
&lt;p&gt;This is why the doctor you&apos;ve been seeing for twenty years can tell something&apos;s off just by looking at you. They have data the chart doesn&apos;t.&lt;/p&gt;
&lt;p&gt;Your app needs the same thing. Not your context but your user&apos;s context. The history, the preferences, the constraints, the patterns. The boring details that change everything.&lt;/p&gt;
&lt;p&gt;There are tools for this: RAG, memory layers, wikis, glossaries. Markdown and vector databases are your friends. But the tools are the easy part. The hard part is deciding what&apos;s worth remembering, and asking for it without making your user feel interrogated.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A painkiller app builds a relationship.
A vitamin app runs a query.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Sell to &lt;em&gt;businesses&lt;/em&gt;, not consumers&lt;/h2&gt;
&lt;p&gt;This one is harder to swallow, but it&apos;s the truth.&lt;/p&gt;
&lt;p&gt;Unless you&apos;re a former senior LLM engineer at Google who also spent three years at Palantir teaching neural networks to sound human, nobody is going to care about your consumer AI app. Here&apos;s why.&lt;/p&gt;
&lt;p&gt;Consumers are drowning. They already have N8n, Lovable, Gemini, Claude, ChatGPT, every Lovable clone, and twelve other free tools they signed up for last month and forgot about. Their phone is a graveyard of apps they don&apos;t remember installing. Yours will join the pile by Friday.&lt;/p&gt;
&lt;p&gt;Now add the supply side. Meta, Microsoft, Amazon, Cloudflare, Google, Oracle — all of them are laying off. If you think you&apos;re smart, imagine what a senior engineer with ten years at Meta and a layoff package can build. And can you walk into an investor meeting and pitch your idea? Because plenty of those people can, and many already have. You&apos;re not competing for users. You&apos;re competing against hundreds of Lamine Yamals for a place on the squad.&lt;/p&gt;
&lt;p&gt;Businesses are different. They&apos;re not chasing the latest model release. They&apos;re stuck on running old software full of their entire history, weighed down by bureaucracy nobody has the appetite to rewrite.&lt;/p&gt;
&lt;p&gt;The company that makes toilet paper? That&apos;s your ideal customer.&lt;/p&gt;
&lt;p&gt;I live in Andalusia. Andalusians don&apos;t like apps. They like WhatsApp. Send ten emails to ten businesses and wait a day for an answer. Send a WhatsApp message and you&apos;ll have a reply in an hour. That&apos;s the gap. That&apos;s where the work is.&lt;/p&gt;
&lt;p&gt;The law firm from Pillar 1 won&apos;t switch off the giant legacy system that owns their entire workflow. But the lawyer will happily pay a monthly fee for something that organizes their files and saves them four hours a week. The small business in Marbella will not learn a new app to automate their customer support, but they would absolutely pay for something that replies on WhatsApp to their multilingual customers without them lifting a finger.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Consumers want the coolest thing.
Businesses want the boring problem solved.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Signals, &lt;em&gt;not analytics&lt;/em&gt;&lt;/h2&gt;
&lt;p&gt;Stop staring at your dashboard. Bounce rate, exit pages, keyword breakdowns. That&apos;s the autopsy. You want the heartbeat.&lt;/p&gt;
&lt;p&gt;Look at how your users actually use the app. What frustrates you in the apps you use every day? I was talking to a friend who runs engineering at a big company, and I asked him what bothered him about an internal tool. His answer wasn&apos;t &quot;the model is wrong&quot; or &quot;it&apos;s slow.&quot; He said he felt overwhelmed by the UI. Sometimes he just wanted to find a button.&lt;/p&gt;
&lt;p&gt;This guy ships software for a living. If he&apos;s lost in your UI, your average user gave up three screens ago.&lt;/p&gt;
&lt;p&gt;If you can talk to your users, talk to them. If you can&apos;t, or if like me you&apos;d rather build than schmooze, there are tools for it. Microsoft Clarity. PostHog. They show you where users stop, where they click, where the mouse hovers, where they rage-quit. That&apos;s gold. Your bounce rate isn&apos;t a number to optimize. It&apos;s a symptom of something you haven&apos;t looked at yet.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;This post is based on my experience building products — one I sold, though it didn&apos;t make me rich — and a lot of time observing and talking to small businesses. It&apos;s incredible what you can learn from a business owner just by asking &lt;em&gt;&quot;Hey, how was your last week?&quot;&lt;/em&gt; and shutting up long enough to listen.&lt;/p&gt;
&lt;p&gt;Now go build that lawyer automation tool that&apos;s going to make you rich. 😉&lt;/p&gt;</content:encoded></item><item><title><![CDATA[The Framing Effect & The Halo Effect: How Marbella Wins the Tourist Race in Andalucía]]></title><description><![CDATA[Today I learned about two interesting psychology concepts: the framing effect and the halo effect. I know I should stop reading non fiction…]]></description><link>https://www.antoniofullone.com/blog/framing-halo-effect</link><guid isPermaLink="false">https://www.antoniofullone.com/blog/framing-halo-effect</guid><pubDate>Sat, 21 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Today I learned about two interesting psychology concepts: &lt;strong&gt;the framing effect&lt;/strong&gt; and &lt;strong&gt;the halo effect&lt;/strong&gt;. I know I should stop reading non fiction books, but I can&apos;t get myself away from it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The framing effect&lt;/strong&gt; is a cognitive bias where people make decisions based on how options are presented with positive or negative connotations, rather than on the facts themselves.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The halo effect&lt;/strong&gt; is a cognitive bias where one positive trait of a person or product leads observers to assume that other positive, unrelated traits also exist.&lt;/p&gt;
&lt;p&gt;So how do these two relate to Marbella? Because Marbella has a very interesting story.&lt;/p&gt;
&lt;p&gt;In the early 1950s, Marbella was just a small fishing village. Nothing else. Until one person bought the &lt;strong&gt;Marbella Club Hotel&lt;/strong&gt; in 1954, aiming to create a private retreat for European nobility, celebrities, and high society. They saw the opportunity and framed the entire town around it. That single decision shaped everything that followed.&lt;/p&gt;
&lt;p&gt;Now look at today&apos;s Marbella: compared with Dubai or other luxury destinations, famous people constantly visiting. We get the luxury part. But how did it reach the point of becoming such a popular place?&lt;/p&gt;
&lt;p&gt;One name above all: &lt;strong&gt;Prince Alfonso von Hohenlohe&lt;/strong&gt;. He&apos;s the one who bought the Marbella Club Hotel, invited his aristocratic friends, hosted a wedding that the European elite attended, and created an experience worth talking about.&lt;/p&gt;
&lt;p&gt;Now fast forward to today and look at what happens.&lt;/p&gt;
&lt;h2&gt;The Framing Effect&lt;/h2&gt;
&lt;p&gt;A tourist in a cold country sees advertising and videos of Marbella online. The town is marketed as beautiful, 300 days of sun (probably more than that, honestly). They see palm trees, gorgeous beaches, those nice &lt;em&gt;chiringuitos&lt;/em&gt; on the sand, and they start imagining themselves there.&lt;/p&gt;
&lt;p&gt;So for once, the tourist decides to skip their classic holidays in the south of their own country and flies to Málaga — because they want to visit Marbella.&lt;/p&gt;
&lt;p&gt;The framing effect kicks in the moment they land. The sun hits their brain, serotonin gets released, and suddenly they&apos;re happy. They pick up the cheap rental car they booked online and drive to Marbella.&lt;/p&gt;
&lt;p&gt;They don&apos;t need to see the town. They don&apos;t need to focus on the beauty. Marbella is &lt;em&gt;already&lt;/em&gt; beautiful to them, and because of that, they fall in love before they&apos;ve really looked. They go to Puerto Banús, see the yachts, the famous faces, the Dolce &amp;#x26; Gabbana café, and then they make those viral videos showing the marina (it&apos;s very small and it&apos;s always the same street if you look closely) saying &lt;em&gt;&quot;should I live here?&quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This is the framing effect. And now I see how Apple uses the same trick every time they present a new iPhone that is basically the same as the last one. Just another one.&lt;/p&gt;
&lt;p&gt;This is also very similar to something I&apos;ve personally experienced as someone who moved from one country to another. It&apos;s called &lt;strong&gt;the honeymoon phase&lt;/strong&gt;, where everything in the new country feels beautiful and better compared to what you left behind.&lt;/p&gt;
&lt;h2&gt;The Halo Effect&lt;/h2&gt;
&lt;p&gt;Now that the tourist is head over heels, they walk into a bar and order a coffee for €5. They think it&apos;s nice. It&apos;s not. Do the sugar test and see for yourself.&lt;/p&gt;
&lt;p&gt;Or they have a cappuccino for €8. Okay, the cappuccino is fine, I can confirm that. But &lt;em&gt;for the love of God&lt;/em&gt;, in Calabria you get a whole pizza for that.&lt;/p&gt;
&lt;p&gt;Then they have Carbonara for €40, or some nice sushi for €80–90. For my Roman friends, yes they make Carbonara with guanciale and no cream.&lt;/p&gt;
&lt;p&gt;They love everything. They go on Google Maps and rate it all 5 stars.&lt;/p&gt;
&lt;p&gt;But here&apos;s the psychological trick: it doesn&apos;t matter whether the food is actually good or not. The halo effect means they love the food &lt;em&gt;regardless&lt;/em&gt; — because they already love the place.&lt;/p&gt;
&lt;h2&gt;The Result&lt;/h2&gt;
&lt;p&gt;These two effects combined made Marbella what it is today — a luxury destination that competes with Dubai, Miami, and the rest.&lt;/p&gt;
&lt;p&gt;But if you expand the view a little and travel around Andalucía, you discover that yes, Marbella is beautiful and it truly lives up to expectations. Seriously, come visit, you won&apos;t be disappointed. But in Andalucía, Marbella is just &lt;em&gt;&quot;one of the many.&quot;&lt;/em&gt; Granada, Sevilla, Ronda, Nerja, Cádiz. White villages. Stunning nature.&lt;/p&gt;
&lt;p&gt;Marbella is just one of them. Because Andalucía is incredibly beautiful and full of towns and villages that rival Marbella. But Marbella found the right positioning, and used these two psychological effects, whether they knew it or not.&lt;/p&gt;
&lt;p&gt;Ask any Andalusian who doesn&apos;t live in Marbella and they&apos;ll tell you: &lt;em&gt;it&apos;s just a town.&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;So in the end, Marbella can be compared to &lt;strong&gt;Sofía Vergara&lt;/strong&gt;. Beautiful, elegant, impossible to ignore.&lt;/p&gt;
&lt;p&gt;But put Sofía in Colombia, and she becomes just &lt;em&gt;&quot;one of the many.&quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How you present yourself makes the difference.&lt;/strong&gt; Marbella rose from one single event and two psychological effects.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Does it make sense to discuss about coding anymore?]]></title><description><![CDATA[The answer, in my humble opinion, is no. Human coding is dead, and so are Stack Overflow, CSS tricks, inverted binary trees, LeetCode and…]]></description><link>https://www.antoniofullone.com/blog/frontend-is-dead</link><guid isPermaLink="false">https://www.antoniofullone.com/blog/frontend-is-dead</guid><pubDate>Sun, 15 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The answer, in my humble opinion, is no. Human coding is dead, and so are Stack Overflow, CSS tricks, inverted binary trees, LeetCode and whiteboard interviews. IDEs are going to be dead soon. Markdown is the new HTML.&lt;/p&gt;
&lt;p&gt;AI has changed the landscape in a way nobody imagined. This is the Industrial Revolution of software. A master weaver in 1780 could produce cloth no machine could match. Intricate, precise, beautiful. By 1820, a child operating a power loom could outproduce him fifty to one. The weaver&apos;s skill didn&apos;t become worthless because it got worse. It became worthless because it &lt;em&gt;stopped being rare&lt;/em&gt;. That&apos;s exactly where we are.&lt;/p&gt;
&lt;p&gt;And this is why frontend engineering, as we know it, is dead. It was a nice run, we all had fun. We got free lunches, ping pong tables, PlayStation, conference tickets and great salaries. It was fun while it lasted. We are the new weavers.&lt;/p&gt;
&lt;h3&gt;How do we survive this wave?&lt;/h3&gt;
&lt;p&gt;Shift your perspective: you&apos;re not the football player anymore, you&apos;re the &lt;strong&gt;head coach&lt;/strong&gt;. Agents, skills, and LLMs are your players. Your job is to make them play well together.&lt;/p&gt;
&lt;p&gt;The future is &lt;strong&gt;product engineering&lt;/strong&gt;. Owning the whole process, not just the codebase. Understanding backend, frontend, product, design. Talking to customers. Building reliable systems. Companies will need &lt;em&gt;thinkers&lt;/em&gt;, not ticket solvers.&lt;/p&gt;
&lt;h3&gt;Process is the real skill.&lt;/h3&gt;
&lt;p&gt;I built 10 apps in recent months. My main focus has never been the code, it&apos;s been refining a winning process. Orchestrate, organize, refine, review, QA, refine again. Take notes of what breaks, repeat until it&apos;s solid. I do more QA than code review. I research. I study how users behave. I have a framework that spins up a full app (Next.js, Supabase, Google Auth, Stripe) in one command. Login, pricing, database, all ready. My worry is how to get the user to &lt;em&gt;pay&lt;/em&gt;, not how to name a variable. This is already happening at work too: most of my time goes into reviewing and instructing, not writing code.&lt;/p&gt;
&lt;p&gt;Your portfolio lives in your building process now, not on GitHub. Replace those green contribution squares with slides that show your thinking, your decisions, your system. &lt;em&gt;That&apos;s&lt;/em&gt; what matters.&lt;/p&gt;
&lt;p&gt;One thing I&apos;ve learned using AI both at work and in personal projects: always play the Italian style. The infamous &lt;em&gt;catenaccio&lt;/em&gt;. Stay on the defensive, never trust it blindly.&lt;/p&gt;
&lt;h3&gt;UX matters more than ever.&lt;/h3&gt;
&lt;p&gt;In a world of shadcn/ui Tailwind wrappers, your &lt;strong&gt;UX expertise&lt;/strong&gt; is what makes the difference. Users are overwhelmed with AI tools today. Most of them fail, hallucinate, have no idea who their ideal user is. Real UX thinking is the purple cow.&lt;/p&gt;
&lt;h3&gt;Human connection still wins.&lt;/h3&gt;
&lt;p&gt;For years we focused on our shiny tickets, pull requests, code reviews. Now if you want to survive, you have to understand your users. Talk to them. AI can&apos;t catch that frustrated sigh, that confused pause, that &quot;ah-ha&quot; moment on someone&apos;s face. In a web built by agents but still used by humans, &lt;em&gt;you&apos;re&lt;/em&gt; the one who bridges the gap.&lt;/p&gt;
&lt;p&gt;Remember JavaScript fatigue? That was nothing. The pace now is relentless. Be ready to keep up, or get comfortable being left behind.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[How I built MagistrOS the intelligent teacher assistant for classroom]]></title><description><![CDATA[MagistrOS, MagistrOS app, is my most ambitious project so far. It helps teachers spot early warning signs in their classrooms, like students…]]></description><link>https://www.antoniofullone.com/blog/building-magistros</link><guid isPermaLink="false">https://www.antoniofullone.com/blog/building-magistros</guid><pubDate>Sun, 08 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;MagistrOS, &lt;a href=&quot;https://www.magistros.app&quot;&gt;MagistrOS app&lt;/a&gt;, is my most ambitious project so far. It helps teachers spot early warning signs in their classrooms, like students slipping behind. It connects to Google Classroom to import data, and it is fully GDPR-compliant: data stays in the EU, and student data is never exposed.&lt;/p&gt;
&lt;p&gt;It can create lessons and assignments from URLs, PDFs, or plain text, while keeping student data inside the classroom context.&lt;/p&gt;
&lt;p&gt;At the core of MagistrOS is &lt;strong&gt;Magi&lt;/strong&gt;, a smart chatbot that can answer questions about classroom data, draft parent reports based on grounded real data, and even add behavioral logs for students.&lt;/p&gt;
&lt;p&gt;I built MagistrOS because I wanted to learn what RAG really is and how it works behind the scenes. Wrappers hallucinate, and when it comes to sensitive K-12 data, doing things properly is critical. I also run &lt;a href=&quot;https://quizgeniusai.com&quot;&gt;QuizGeniusAI&lt;/a&gt;, which has grown organically to &lt;strong&gt;650 users&lt;/strong&gt; (many of them teachers), so I wanted to extend that concept beyond simple quizzes.&lt;/p&gt;
&lt;p&gt;I used two main skills for this project, &lt;code&gt;rag-engineer&lt;/code&gt; and &lt;code&gt;rag-implementation&lt;/code&gt;. I wanted to compare how they performed during planning vs. execution, and also see whether Codex or Claude Code handled RAG better.&lt;/p&gt;
&lt;p&gt;I started planning with Gemini. I ran research on Google Classroom: weaknesses, teacher complaints, countries with highest usage (USA, UK, Sweden, Indonesia), platform evolution, and competitor strategy. After that, I ran my own “complaint crawler,” an app I built to search the web and Reddit for complaints and discussions on specific topics.&lt;/p&gt;
&lt;p&gt;Once I had the initial concept and the main three features, I moved to Codex in plan mode. I pasted the full Gemini conversation and asked Codex to challenge it with fresh research. Codex performed very well in research and produced a complete plan, including the RAG system. Then, in a separate chat, I used the &lt;code&gt;rag-implementation&lt;/code&gt; skill to review that plan, especially the RAG section. I finally pasted the plan in to Claude Code for the last iterations and implementation.&lt;/p&gt;
&lt;p&gt;Codex handled most of the UI work. The &lt;code&gt;frontend-design&lt;/code&gt; skill was strong, and I explicitly asked not to use shadcn. The layout turned out well. Claude Code handled the initial RAG implementation, including a mock seeding system so I could always test with data.&lt;/p&gt;
&lt;h2&gt;Main RAG Issues I Had to Fix&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Wrong voice for the real user&lt;/strong&gt;&lt;br&gt;
Early outputs sounded like tooling docs for engineers, not guidance for teachers. I had to rewrite prompts and clean up i18n strings so responses were plain, practical, and classroom-friendly.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Low-evidence behavior was unstable&lt;/strong&gt;&lt;br&gt;
When retrieval confidence dropped, answers were either generic or too weak to be useful. This was the hardest part. I moved high-stakes flows to strict grounding, so the assistant now says what is missing instead of guessing.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Retrieval quality needed heavy tuning&lt;/strong&gt;&lt;br&gt;
Dense search alone missed obvious context. Lower thresholds improved recall but also introduced noisy matches. I had to tune thresholds, add hybrid retrieval (semantic + lexical), and reranking before results became consistent.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Debugging was blind at first&lt;/strong&gt;&lt;br&gt;
Without clear retrieval diagnostics, every bad answer looked the same. Adding retrieval-quality logs and claim/retrieval audits made it possible to separate data gaps from prompt issues and fix the right layer.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What looked like “just tuning RAG” became a full trust pipeline: voice, retrieval, evidence validation, and safe fallback behavior all had to work together.&lt;/p&gt;
&lt;h2&gt;The Bigger Problem: Trust&lt;/h2&gt;
&lt;p&gt;The main issue in this app is the same issue I had in previous apps: &lt;strong&gt;trust&lt;/strong&gt;. Teachers rarely trust an app they do not know, especially when it asks to import classroom data. Google is already under scrutiny for student login and data concerns, so the bar is high.&lt;/p&gt;
&lt;p&gt;I ran a full review with &lt;strong&gt;Perplexity&lt;/strong&gt; on the landing page and the core concept. After several iterations, I implemented these changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I built a mock-data demo so teachers can see how the app works before connecting anything.&lt;/li&gt;
&lt;li&gt;I ask for minimal permissions at login, then request broader permissions only when the teacher decides to connect.&lt;/li&gt;
&lt;li&gt;I built an IT page showing exactly what data is used and how it is handled.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;According to my own brain intelligence (no AI needed), apps like this can be killed by Google with one small move. So I planned MagistrOS not to depend entirely on Classroom. For example, assignments can be created and shared in Classroom, but also outside of it.&lt;/p&gt;
&lt;p&gt;One strong product idea came from Claude (app, not code): teachers can generate server-side PIN codes that map to students names (also verified server side, never exposed), so students do not need to log in or expose personal data. The PIN codes use fun, child-friendly names, which turned out to be a smart UX choice.&lt;/p&gt;
&lt;p&gt;I think MagistrOS has real potential, but like with most of my apps, I still struggle with promotion. No social media and no marketing expertise are my biggest limits.&lt;/p&gt;
&lt;p&gt;Anyway, this was a very fun project. I learned a lot, not just about RAG, but also about privacy, handling sensitive data, and difficult marketing.&lt;/p&gt;
&lt;p&gt;Even more fun: writing this while seeing Kimi and Charles both on the podium. That early wake-up was worth it.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Un pesce fuor d'acqua]]></title><description><![CDATA[Since computers and internet existed, every engineer had a side project that they were working on. Today with the rise of AI everyone is…]]></description><link>https://www.antoniofullone.com/blog/fish-out-of-water</link><guid isPermaLink="false">https://www.antoniofullone.com/blog/fish-out-of-water</guid><pubDate>Sun, 01 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Since computers and internet existed, every engineer had a side project that they were working on. Today with the rise of AI everyone is building, and they are all hoping to become the next billion dollars unicorn.&lt;/p&gt;
&lt;p&gt;I am building too, honestly I would be just happy to build something that pays me off my mortgage.&lt;/p&gt;
&lt;p&gt;The moment is absolute peak, but this is not easy for me. I quit social media about 7-8 years ago but I had already stopped using them for some years. And I don&apos;t know how to promote my apps or get users feedbacks.&lt;/p&gt;
&lt;p&gt;I thought it could be a good idea to &quot;come back&quot; online, so that I can somehow promote my projects. I tried a few social network and well, it didn&apos;t go as planned. I felt completely out of touch with basically everything I have seen today, like a fish out of water, &lt;em&gt;un pesce fuor d&apos;acqua&lt;/em&gt; as we say in Italian, which sounds more romantic.&lt;/p&gt;
&lt;h2&gt;Here is a quick recap of my experience:&lt;/h2&gt;
&lt;h3&gt;Facebook&lt;/h3&gt;
&lt;p&gt;I lasted one week, most of it spent trying to fix the privacy settings while also trying to setup a meta business account for ads and promote 2 pages. Meanwhile Facebook thinks it&apos;s ok to show me promoted pages about fascism, hate and controversial posts that I could not give a damn.&lt;/p&gt;
&lt;h3&gt;Instagram&lt;/h3&gt;
&lt;p&gt;I lasted 2 weeks more or less. This is just an OnlyFans funnel, nothing else. I don&apos;t know if the models are AI or real, but the amount of women willing to show their body to thousands of perverts (I read the comments) for some likes is astonishing. I am pretty sure they make money out of it. There are nice real videos, but turns out most of them are from TikTok.&lt;/p&gt;
&lt;h3&gt;LinkedIn&lt;/h3&gt;
&lt;p&gt;Cringe is the right word for LinkedIn. I never deleted my account, I simply switched my location to Papua New Guinea to skip spam. But this app is cringe, like everyone has some employees who are either too old, too good, too fired, whatever. Then there is someone who writes a post clearly written by AI on how they cracked the code to use Claude Code and make trillions and the only thing you have to do is to comment &quot;Claude&quot; on their post. I am still wrapping my mind around this, I just don&apos;t get it. I also deleted a few posts that I wrote to promote the apps, they felt cringe too.&lt;/p&gt;
&lt;h3&gt;TikTok&lt;/h3&gt;
&lt;p&gt;People that don&apos;t know how to dance, are dancing in front of a phone, no reason given, they call their followers &quot;fans&quot;. A bit of the Instagram vibe here too, just that ... the age ... is lower ... and is kinda creepy. I am now terrified of eating alone in a restaurant, someone might make a black and white of me and post it there.&lt;/p&gt;
&lt;p&gt;With TikTok it&apos;s pretty easy to trick the algorithm so I kept the app because now I can re-watch all South Park, Family Guy and Tom and Jerry sketches, which I love.&lt;/p&gt;
&lt;h3&gt;Reddit&lt;/h3&gt;
&lt;p&gt;All of the above, plus a bit of  trumpy touch. Everyone shouts and demeans others, everyone is building AI wrappers, everyone is spamming their new app (some built some incredibly good bots for it). I asked in an official GitHub forum if I could get some feedback, without posting a link of the app, and got banned.&lt;/p&gt;
&lt;h3&gt;Back to my cave&lt;/h3&gt;
&lt;p&gt;It&apos;s basically impossible for me to use again social media, be active on it, and not to feel weird. So I decided to go back to my cave. I started blogging again because why not, I am already an old fashioned engineer who wears a coppola, drives an old 1971 Vespa Special R. and watches Sergio Leone&apos;s movies. Blogging fits right in.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Learning to swim]]></title><description><![CDATA[Summer in my hometown is long and nice. When I was a kid we used to go to spend all day at the beach. My favorite moment was when my dad…]]></description><link>https://www.antoniofullone.com/blog/learning-swim</link><guid isPermaLink="false">https://www.antoniofullone.com/blog/learning-swim</guid><pubDate>Fri, 24 Sep 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Summer in my hometown is long and nice. When I was a kid we used to go to spend all day at the beach. My favorite moment was when my dad would come after work, I can still picture in my mind every frame of that moment, his blue shirt opened up a bit to show part of the chest, the short sleeve raised above the arm, the pants similar to those used in tennis with colored pockets, and Ray-Ban sunglasses, of course.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/posts/my-first-birthday.jpg&quot; alt=&quot;my first birthday&quot;&gt;&lt;/p&gt;
&lt;p&gt;I would look at him in awe, then wait the moment he will join us in the water. We used to go far away, me following him with a large donut-shaped lifebuoy. One day, when I was 7 or 8 yo, he asked me if I wanted to learn to swim. I remember we were so far that I could barely see my mother standing and waving hands to us, probably screaming at my father why he took me so far. I did not even think a second and said yes, so he started explaining to me how to do it and moved a bit far from me, right after he had pinched a hole in my donut, I realized that the donut was deflating. The first seconds I panicked and started looking around very scared, trying to find his face. I saw him few meters away from me, laughing. I started moving and reached him, and he was like &quot;you see, you did it!&quot;. I swam!&lt;/p&gt;
&lt;p&gt;He told me lay on his back and grab him, and so I did. We reached the land and boy, that trip was one of the most beautiful moments of my life. I never felt so safe, so strong.&lt;/p&gt;
&lt;p&gt;When my father passed away, I was devastated. I felt like the first moments when my &quot;donut&quot; started deflating, but the difference is that he would not be there, no matter where I looked. I spent a lot of time denying his death to myself, I even refused for years to go to visit his grave.&lt;/p&gt;
&lt;p&gt;That feeling of being lost at sea has followed me for many years and made me make many mistakes, but the biggest mistake I did was trying to be &quot;like him&quot;. It took me way too many years to understand that this cannot be possible.&lt;/p&gt;
&lt;p&gt;Talking to a dear friend recently I got this very simple answer:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You cannot be like him because we are all different, you cannot be someone else you got to be yourself.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It&apos;s true, but what I also realized only recently is that well, I am not him but &lt;strong&gt;I am the person that he always wanted me to be.&lt;/strong&gt; and that makes me incredibly proud.&lt;/p&gt;
&lt;p&gt;A quote from my favorite books says&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Every man is worth just as much as the things he busies himself with.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I have been busy in the last years building a better self, and what helped me in that was to embrace my father&apos;s principles, first of all, the love for the family. And I am quite proud of the results I got.&lt;/p&gt;
&lt;p&gt;My dad passed away on the same day as my birthday, the 24th of September. I have never celebrated my birthday since then, I hate this day, I hate the whole month of September.&lt;/p&gt;
&lt;p&gt;I have just one big dream in my life and make this dream come true is the best way to keep my father&apos;s legacy alive, and honor him.&lt;/p&gt;
&lt;p&gt;Today I won&apos;t celebrate, but I look forward to the day that I make this dream come true and when that day comes, I want to sit at the head of the table put my favorite &lt;a href=&quot;https://en.wikipedia.org/wiki/Coppola_cap&quot;&gt;coppola&lt;/a&gt; on, grab a glass of wine and say&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Happy birthday to me&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Create a GraphQl app with PostgreSQL, Hasura, React and Apollo client.]]></title><description><![CDATA[I am having quite a lot of fun recently working with GraphQl in some personal projects. I am understanding the real advantages of using it…]]></description><link>https://www.antoniofullone.com/blog/graphql-app-hasura-postgresql-apollo-react</link><guid isPermaLink="false">https://www.antoniofullone.com/blog/graphql-app-hasura-postgresql-apollo-react</guid><pubDate>Sun, 26 Apr 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I am having quite a lot of fun recently working with GraphQl in some personal projects. I am understanding the real advantages of using it and, more important, the fact that finally I can focus 100% on the Front End without caring too much about the backend part (yep, I am not a fullstack guy).&lt;/p&gt;
&lt;p&gt;So let&apos;s see how we can build a simple GraphQl server with Hasura and PostgreSQL and then connect to it from the front end using React and Apollo.&lt;/p&gt;
&lt;p&gt;Let&apos;s start creating our app, let&apos;s make it simple and use create-react-app for that&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-Nodejs&quot;&gt;npx create-react-app graphqlapp &amp;#x26;&amp;#x26; cd graphqlapp
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We install the dependencies we need for it&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-Nodejs&quot;&gt;yarn add apollo-boost @apollo/react-hooks graphql
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And then we can start our app&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-Nodejs&quot;&gt;yarn start
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now it&apos;s time to set up our GraphQl server, nothing could be more easier with Hasura and Heroku. You can check their &lt;a href=&quot;https://hasura.io/docs/1.0/graphql/manual/getting-started/heroku-simple.html&quot;&gt;starting page&lt;/a&gt; or if you prefer just click on &lt;a href=&quot;https://heroku.com/deploy?template=https://github.com/hasura/graphql-engine-heroku&quot;&gt;this link&lt;/a&gt; and wait for your heroku app to be created.&lt;/p&gt;
&lt;p&gt;Next click on view app and you should have your PostgreSQL server running, with GraphQl and also GraphiQL, which is basically a UI for your GraphQL server. I also installed the &lt;a href=&quot;https://github.com/apollographql/apollo-client-devtools&quot;&gt;Apollo devtools&lt;/a&gt; for chrome.&lt;/p&gt;
&lt;p&gt;So let&apos;s leave our app for a second and let&apos;s go to the database. Click on data in to the top level menu and and then click on &lt;strong&gt;add table&lt;/strong&gt; in the left side navigation.&lt;/p&gt;
&lt;p&gt;In this example we will create a simple app for searching our books so let&apos;s add the table books and then we add some fields:
id: integer auto-increment - this is our unique key
title: Character varying
description: Text (we add a brief description of the book)
author: Character varying
added: timestamp (choose now() as default value)&lt;/p&gt;
&lt;p&gt;Keep in mind that I am not an expert on PostgreSQL, and these fields are created based on a quick read of their tutorials. But this is the nice part of GraphQL right? No backend, no need to learn more stuff, we can focus 100% on our front end!&lt;/p&gt;
&lt;p&gt;Let&apos;s add some data to it, I will add 2 of my favorite books:
Meditations by Marcus Aurelius
Atomic habits by James clear&lt;/p&gt;
&lt;p&gt;You can add the books you want and then we have the first 2 items in our database. Let&apos;s go to the GraphiQL UI and let&apos;s try a simple grapqhl query:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;query books {
  books {
    id
    title
    author
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here we are getting our books, but - and this is the nicest part of GraphQL - we are only requesting the id, title and author, we don&apos;t want to have the description in our case.
Hit the &quot;play button&quot; next to GraphQL and in the right column you should see the results, an object like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-Javascript&quot;&gt;{
  &quot;data&quot;: {
    &quot;books&quot;: [
      {
        &quot;id&quot;: 1,
        &quot;title&quot;: &quot;Meditations&quot;,
        &quot;author&quot;: &quot;Marcus Aurelius&quot;
      },
      {
        &quot;id&quot;: 2,
        &quot;title&quot;: &quot;Atomic habits&quot;,
        &quot;author&quot;: &quot;James Clear&quot;
      }
    ]
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Done! One thing to keep in mind, Grahql always returns 200 no matter what is the results. If you are used to rest API, you have now a different way of managing errors. GraphQL will always return an object and this object contains 3 main values:
data - the results of the query
errors - if there is any error (this is how you should manage errors in GraphQL apps)
metadata - extra data (we won&apos;t talk about this for now)&lt;/p&gt;
&lt;p&gt;Now we have our backend setup, let&apos;s move on to the front end.&lt;/p&gt;
&lt;p&gt;If you installed all correctly now it&apos;s time to connect our app to our Graphql server via Apollo client.&lt;/p&gt;
&lt;p&gt;You still need one thing from the server, the GraphQL endpoint. This is visible in GraphiQL. Copy that url and let&apos;s move on with Apollo.&lt;/p&gt;
&lt;p&gt;Open the index.js file in your app and import the Apollo Client:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;import ApolloClient from &apos;apollo-boost&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&apos;s create our client:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;const client = new ApolloClient({
  uri: &apos;https://${YOUR_APP_NAME}.herokuapp.com/v1/graphql&apos;
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We are now ready to fetch our data. Let&apos;s import Apollo Provider. Apollo Provider works like Contect.Provider or styled-components provider, making our client endpoint accessible to all the app.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;import { ApolloProvider } from &apos;@apollo/react-hooks&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&apos;s add it to our APP:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;  &amp;#x3C;React.StrictMode&gt;
    &amp;#x3C;ApolloProvider client={client}&gt;
      &amp;#x3C;App /&gt;
    &amp;#x3C;/ApolloProvider&gt;
  &amp;#x3C;/React.StrictMode&gt;,
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&apos;s create our first query now. We move in to App.js and there we need to import a hook that we will use for querying our database, together with the graphql tag for writing the query:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;import { useQuery } from &apos;@apollo/react-hooks&apos;;
import { gql } from &apos;apollo-boost&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&apos;s write our first query, we can copy the one we used initially in the GraphiQL UI:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;const BOOKS_QUERY = gql`
  {
    books {
      id
      title
      author
    }
  }
`;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now let&apos;s create a simple component that executes the query and renders these results:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-jsx&quot;&gt;const BooksList = () =&gt; {
  const { loading, error, data } = useQuery(BOOKS_QUERY);
  if (loading) {
    return &amp;#x3C;p&gt;Loading results ... &amp;#x3C;/p&gt;;
  }
  if (error) {
    return &amp;#x3C;p&gt; Ops .. something went wrong&amp;#x3C;/p&gt;;
  }
  return data.books.map(book =&gt; (
    &amp;#x3C;div key={book.id}&gt;
      &amp;#x3C;p&gt;title: {book.title}&amp;#x3C;/p&gt;
      &amp;#x3C;p&gt;Author: {book.author}&amp;#x3C;/p&gt;
    &amp;#x3C;/div&gt;
  ));
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What we do here is pretty simple:
First we get the data with &lt;code&gt;useQuery&lt;/code&gt; as I said before Graphql always returns 200 as response, but Apollo does the good job of handling the error for us, same for the loading state.&lt;/p&gt;
&lt;p&gt;Let&apos;s change our App.js to use the &lt;BooksList&gt; component:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-jsx&quot;&gt;&amp;#x3C;div className=&quot;App&quot;&gt;
  &amp;#x3C;header className=&quot;App-header&quot;&gt;
    &amp;#x3C;BooksList /&gt;
  &amp;#x3C;/header&gt;
&amp;#x3C;/div&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If everything went fine you should see the list in your App!&lt;/p&gt;
&lt;p&gt;That&apos;s it! It was more easy than it looked. Have fun with GraphQL!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[How to publish your first NPM Package]]></title><description><![CDATA[Some time ago I created my first npm package. I am not really an open source person since I never had much time to get involved, but once I…]]></description><link>https://www.antoniofullone.com/blog/how-publish-your-first-npm-package</link><guid isPermaLink="false">https://www.antoniofullone.com/blog/how-publish-your-first-npm-package</guid><pubDate>Sun, 19 Apr 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Some time ago I created my &lt;a href=&quot;https://www.npmjs.com/package/react-fluid-text&quot;&gt;first npm package&lt;/a&gt;. I am not really an open source person since I never had much time to get involved, but once I built this small component for my website I decided to publish it, and in the process I learned a bit about &lt;strong&gt;building and publishing a package to NPM&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;In this post I will focus on React. We will build a React component with a basic template and we will publish it to NPM.
The source code is available on &lt;a href=&quot;https://github.com/antoniofull/npm-package-react-template&quot;&gt;Github&lt;/a&gt; and in the &lt;a href=&quot;https://www.npmjs.com/package/npm-package-react-template&quot;&gt;NPM registry&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Let&apos;s not waste any more time and let&apos;s get started with coding.&lt;/p&gt;
&lt;p&gt;We start creating the folder&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-node&quot;&gt;mkdir npm-react-template-package
cd npm-react-template-package
git init
yarn init -y
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These steps should be familiar to all, we just create the folder and we initialize Git and Yarn so now our folder contains the package.json file. Change the &lt;code&gt;main: index.js&lt;/code&gt; to &lt;code&gt;lib/index.js&lt;/code&gt; so we have a little bit more of order in
Let&apos;s add the licence and keywords too.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-NODE&quot;&gt;&quot;keywords&quot;: [
    &quot;reactjs, template&quot;
  ],
  &quot;license&quot;: &quot;MIT&quot;,
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can modify your package.json file with your data. Next let&apos;s add the .gitignore file, we can use the one from &lt;a href=&quot;https://raw.githubusercontent.com/github/gitignore/master/Node.gitignore&quot;&gt;Github&lt;/a&gt;. Create your &lt;code&gt;.gitignore&lt;/code&gt; file in the root folder and copy and paste the raw code.&lt;/p&gt;
&lt;p&gt;Now it&apos;s time to add some dependencies&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-NODE&quot;&gt;yarn add @babel/core @babel/preset-env @babel/preset-react babel-cli babel-loader webpack webpack-cli react react-dom prop-types -D
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We will use webpack and babel to transpile the code. For babel to work we need to create a file called &lt;code&gt;.babelrc&lt;/code&gt; so let&apos;s create it and add&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-NODE&quot;&gt;{
  &quot;presets&quot;: [&quot;@babel/preset-react&quot;, &quot;@babel/preset-env&quot;]
}

```NODE
I guess this doesn&apos;t need any extra explanation. Now right before the devDependencies we add the peerDependencies.

```NODE
&quot;peerDependencies&quot;: {
    &quot;prop-types&quot;: &quot;^15.7.2&quot;,
    &quot;react&quot;: &quot;^16.10.1&quot;,
    &quot;react-dom&quot;: &quot;^16.10.1&quot;
 }

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;PeerDependencies are dependencies that are not installed automatically when running npm install, but are required by the code that will use the package. &lt;a href=&quot;https://flaviocopes.com/npm-peer-dependencies/&quot;&gt;Flavio does a great job ( as usual, you should follow him) explaining what peerDependencies are&lt;/a&gt;. So if you are curious go and check it out.&lt;/p&gt;
&lt;p&gt;Before starting to create our component we need the last thing, we need the script in package.json to build the code. Before the peerDependencies let&apos;s add our build script.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-NODE&quot;&gt; &quot;scripts&quot;: {
    &quot;build&quot;: &quot;rm -rf lib &amp;#x26;&amp;#x26; webpack&quot;
 }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&apos;s now add our first file. We need a classic &lt;code&gt;webpack.config.js&lt;/code&gt; file so let&apos;s create one and let&apos;s add the code.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-JS&quot;&gt;var path = require(&apos;path&apos;);

module.exports = {
  mode: &apos;production&apos;,
  entry: &apos;./src/index.js&apos;,
  output: {
    path: path.resolve(&apos;lib&apos;),
    filename: &apos;index.js&apos;,
    libraryTarget: &apos;commonjs2&apos;
  },
  externals: {
    react: &apos;react&apos;,
    &apos;react-dom&apos;: &apos;reactDOM&apos;,
    &apos;prop-types&apos;: &apos;prop-types&apos;
  },

  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        resolve: {
          extensions: [&apos;.js&apos;, &apos;.jsx&apos;]
        },
        use: {
          loader: &apos;babel-loader&apos;
        }
      }
    ]
  }
};

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you work with React you have probably also worked with webpack so not much new, the only confusing part might be the &lt;code&gt;externals&lt;/code&gt;. &lt;a href=&quot;https://webpack.js.org/configuration/externals/&quot;&gt;Externals&lt;/a&gt; are used in webpack when we want to exclude those files from the build. Since we do not want to ship our package with React and prop-types we tell webpack to exclude it. The rest is pretty simple and basic webpack configuration.&lt;/p&gt;
&lt;h3&gt;Time to create and publish our first NPM component!&lt;/h3&gt;
&lt;p&gt;So we are ready to go and now we can create our custom component. Let&apos;s add a &lt;code&gt;src&lt;/code&gt; folder and inside we create a file called &lt;code&gt;index.js&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Our component will be very simple, just a classic Hello World! so let&apos;s add it&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-JS&quot;&gt;import React from &apos;react&apos;

export default () =&gt; &amp;#x3C;h1&gt;Hello World!&amp;#x3C;/h1&gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&apos;s now run the build command: &lt;code&gt;yarn build&lt;/code&gt; if everything worked fine, now we have our component ready to be used inside the &lt;code&gt;lib&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Before testing it our component works, let&apos;s add a quick test. I won&apos;t go much in details, maybe another time, I will be using testing library for React and Jest so let&apos;s add them&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-NODE&quot;&gt;yarn add @testing-library/react jest  -D
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we create a folder called &lt;code&gt;__tests__&lt;/code&gt; and we add our &lt;code&gt;MyComponent.test.js&lt;/code&gt;. Open the newly created file and let&apos;s add a simple test&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-JS&quot;&gt;import React from &apos;react&apos;
import { render, cleanup } from &apos;@testing-library/react&apos;
import MyComponent from &apos;../src&apos;

afterEach(cleanup)

describe(&apos;&amp;#x3C;MyComponent&gt;&apos;, () =&gt; {
  it(&apos;matches snapshot&apos;, () =&gt; {
    const { asFragment } = render(&amp;#x3C;MyComponent /&gt;)
    expect(asFragment()).toMatchSnapshot()
  })
})

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Run &lt;code&gt;yarn jest&lt;/code&gt; and check that everything is fine and the test passes, writing the snapshot inside its own folder. We then add the test command to package.json&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-NODE&quot;&gt; &quot;test&quot;: &quot;yarn jest&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We are good to go. Now for testing the component we could use &lt;code&gt;npm link&lt;/code&gt; but for make things easier I will just import the component from the lib folder, this is because we will ad an example folder direcly in our repo.&lt;/p&gt;
&lt;p&gt;Let&apos;s create a folder called example and let&apos;s follow these steps&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-NODE&quot;&gt;yarn init -y
yarn add react react-dom
yarn add @babel/core @babel/preset-env @babel/preset-react babel-loader html-webpack-plugin webpack webpack-cli webpack-dev-server -D
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&apos;s add the scripts to the package.json&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-NODE&quot;&gt;  &quot;scripts&quot;: {
    &quot;build&quot;: &quot;webpack&quot;,
    &quot;start&quot;: &quot;webpack-dev-server&quot;,
    &quot;test&quot;: &quot;echo \&quot;Error: no test specified\&quot; &amp;#x26;&amp;#x26; exit 1&quot;
  }

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then the webpack.config.js&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-JS&quot;&gt;const HtmlWebpackPlugin = require(&apos;html-webpack-plugin&apos;)

module.exports = {
  mode: &apos;development&apos;,
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /(node_modules)/,
        resolve: {
          extensions: [&apos;.js&apos;, &apos;.jsx&apos;],
        },
        options: {
          presets: [&apos;@babel/preset-env&apos;, &apos;@babel/preset-react&apos;],
        },
        loader: &apos;babel-loader&apos;,
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: &apos;./src/index.html&apos;,
    }),
  ],
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we add the index.html file used by webpack to start the server and the basic App.jsx&lt;/p&gt;
&lt;p&gt;Index.html&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-HTML&quot;&gt;&amp;#x3C;!DOCTYPE html&gt;
&amp;#x3C;html lang=&quot;en&quot;&gt;
  &amp;#x3C;head&gt;
    &amp;#x3C;meta charset=&quot;UTF-8&quot; /&gt;
    &amp;#x3C;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;
    &amp;#x3C;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;ie=edge&quot; /&gt;
    &amp;#x3C;title&gt;React Template NPM Component&amp;#x3C;/title&gt;
  &amp;#x3C;/head&gt;
  &amp;#x3C;body&gt;
    &amp;#x3C;div id=&quot;root&quot;&gt;&amp;#x3C;/div&gt;
  &amp;#x3C;/body&gt;
&amp;#x3C;/html&gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;App.jsx&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-JS&quot;&gt;import React from &apos;react&apos;
import MyNPMComponent from &apos;../../lib&apos;

const App = () =&gt; {
  return &amp;#x3C;MyNPMComponent /&gt;
}
export default App

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We import the component direcly from the lib folder, but as I said you could also use &lt;code&gt;npm link&lt;/code&gt; anyway now if you run &lt;code&gt;yarn start&lt;/code&gt; and we open our browser to &lt;code&gt;localhost:8080&lt;/code&gt; we should see our component loaded and the Hello World! text shown.&lt;/p&gt;
&lt;h3&gt;Publish the component to npm&lt;/h3&gt;
&lt;p&gt;In order to publish the component we need to have an account to the &lt;a href=&quot;https://www.npmjs.com/&quot;&gt;NPM website&lt;/a&gt;, if you don&apos;t have one just go and create it.&lt;/p&gt;
&lt;p&gt;Then run &lt;code&gt;npm login&lt;/code&gt; in your terminal, so you can login. Once loggedin you should see something like this&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-NODE&quot;&gt;Logged in as antoniofull on https://registry.npmjs.org/.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next step is to choose a name for our package, I&apos;ll call it &lt;code&gt;npm-package-react-template&lt;/code&gt; and, the most important part, we need to add the version. We can also add a short description and the README file.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/antoniofull/npm-package-react-template/blob/master/package.json&quot;&gt;Here is my final package.json&lt;/a&gt; and the &lt;a href=&quot;https://github.com/antoniofull/npm-package-react-template/blob/master/README.md&quot;&gt;README&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Before hitting the publish button we need a last thing: we want to ignore some files from NPM so we need to add an &lt;code&gt;.npmignore&lt;/code&gt; file, here is:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-NODE&quot;&gt;.babelrc
webpack.config.js
yarn.lock
.DS_Store
src/.DS_Store
example/node_modules
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once done we can finally publish it with &lt;code&gt;npm publish&lt;/code&gt;. If everything worked correctly you should see in the terminal the succesfully response and, usually, you should receive an email from NPM. If not, check the error, the most common error are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Some typos in your package.json o&lt;/li&gt;
&lt;li&gt;No version&lt;/li&gt;
&lt;li&gt;Name of the package already taken.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Fix the errors and then hit the button again, you should be ready to go.
Here is my &lt;a href=&quot;https://www.npmjs.com/package/npm-package-react-template&quot;&gt;final result&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[The simple things]]></title><description><![CDATA[As the rest of the World, I am stuck at home in a sort of self-quarantine.
I am in Barcelona, where I came for work, and I am unable to go…]]></description><link>https://www.antoniofullone.com/blog/corona-virus-and-simple-things</link><guid isPermaLink="false">https://www.antoniofullone.com/blog/corona-virus-and-simple-things</guid><pubDate>Sat, 21 Mar 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;As the rest of the World, I am stuck at home in a sort of self-quarantine.
I am in Barcelona, where I came for work, and I am unable to go back to my home town, where my family lives.&lt;/p&gt;
&lt;p&gt;I took this time alone to reflect on several things and I really want, once this chaos is over, enjoy that little simple daily life actions that, in a normal situation, I would not even notice.&lt;/p&gt;
&lt;h3&gt;Family&lt;/h3&gt;
&lt;p&gt;I am terrified for what is happening in Italy, I have my family there and I cannot go back to stay close to them.
My mother is one of the subject at high risk since she has diabetes and heart problems, my brother in law had a liver transplant and his son, my Godson, had meningitis plus he suffer from a mild form of psoriasis.
I have trouble sleeping at night and I keep having nightmares. I know I am not the only one in this situation, but I realise how much I love my family and how, sometimes, I have been selfish thinking about myself. Like making a plane ticket the day before and go travel somewhere around the world, while maybe my family needed me there. I know this sounds like a real Italian thing but yes, I do love my family more than anything else in this world. I can’t wait to be there and stay with them.&lt;/p&gt;
&lt;h3&gt;Walking&lt;/h3&gt;
&lt;p&gt;I like walking, I have this app that tracks my steps and I usually take my 10.000 steps a day.
When I use to do my walk, I never noticed the environment around me, trees, lakes etc. Next walk I want to really take the time to look around and enjoy the beauty of our mother nature.&lt;/p&gt;
&lt;h3&gt;Pizza&lt;/h3&gt;
&lt;p&gt;I want to go to te restaurant and have a pizza, like a big one and I want it super spicy. I want to have a pizza with my family and another with my colleagues. Yes I want a huge spciy pizza, the one that you can find only down in the south of Italy.&lt;/p&gt;
&lt;h3&gt;Friends&lt;/h3&gt;
&lt;p&gt;I am in constant touch with Bram and Dan, two friends I met in Barcelona in 2009 and since then we have been always in touch through whatsapp. I realise how important is to have friends you can talk to during moment like this. And yes I miss them, and can’t wait to organise a new reunion somewhere in Europe. I also call everyday with Filippo, my best friend, he is in Switzerland and we keep supporting each other, since we have both families down there, in the so-called &lt;code&gt;red zone&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Community&lt;/h3&gt;
&lt;p&gt;During the years, my country and my region have lost that sense of community that was characteristic here in the south. During these days, we are understanding how important is to help each other, we are recovering that sense of community that was lost, mostly due to politics manipulation that is better not to talk about. I really hope people will understand how meaningless and useless is to judge someone for where they come from, how they dress or their skin color.&lt;/p&gt;
&lt;h3&gt;Solidarity&lt;/h3&gt;
&lt;p&gt;My home town is a red zone, the problem is that our hospital, and the ones near by, don’t have the capacity and equipment to deal with a situation like this. Lombardy, the richest region in Italy and the one with the best health system has collapsed, imagine what would happen if Calabria is hit so hard. Yes it is terrifying. In just few days the entire community made a fundraiser and we raised enough money to buy 4 ventilators to help those who will need them. &lt;strong&gt;I think this is the most awesome thing happened since the corona virus breach.&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;I am lucky&lt;/h3&gt;
&lt;p&gt;I have been working remotely for over 3 years, I am not new to it. I work in IT, that means also that I can work from anywhere I want,. Probably I won’t lose my job and I have a salary that gives me the opportunity to help my family in this moment of needs.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I am lucky&lt;/strong&gt;, damn it if I am. Many times I thought how much I fought to get to this point, countless hours on google learning about programming, I always thought I deserved my “fortune”, but now, looking at how many of my friends (and family) are going to lose their job, I can just say that I am extremely lucky. Sure I deserved it, but so many people in this world could not even afford a computer or an internet connection. I have now full awareness of how lucky I am.&lt;/p&gt;
&lt;p&gt;So yes, as soon as this shitty situation is over, I will go back to my home town and have a huge party with my family, then I will call Bram and Dan to organise our reunion, and finally will go to meet Filippo and have some fun with my best friend.&lt;/p&gt;
&lt;p&gt;These are hard moments I know, we are all scared by what is happening, but we are all together in this, and this is the moment to reflect and to understand that we have only one life, we have only one earth and the World is one. We are all together in this, and I hope we will be again all together also when we will be back to enjoy our good moments.&lt;/p&gt;
&lt;p&gt;My father was an inspiring man, he was (and still is) my greatest inspiration. He lived a simple life and he dedicated his (very short) life to the family and the community. I am lucky to have had him as a father, and I am sure that I will be back, one day, to enjoy the little simple things in life, like he did and taught me.&lt;/p&gt;
&lt;p&gt;Stay safe, stay home, stay healthy.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[The Resilient Mindset]]></title><description><![CDATA[If you have read Carol Dweck's book, you know how the author explain the 2 different mindsets, fixed and growth. While the book is really…]]></description><link>https://www.antoniofullone.com/blog/the-resilient-mindset</link><guid isPermaLink="false">https://www.antoniofullone.com/blog/the-resilient-mindset</guid><pubDate>Sat, 07 Dec 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If you have read &lt;a href=&quot;https://www.antoniofullone.com/blog/growth-mindset-fixed-mindset&quot;&gt;Carol Dweck&apos;s book&lt;/a&gt;, you know how the author explain the 2 different mindsets, fixed and growth. While the book is really enjoyable and well written, I feel is missing an important part.&lt;/p&gt;
&lt;p&gt;Most of the example are assuming that there is a kid who grow up in a &quot;normal&quot; family, went to school, played in the school football team, and has a &quot;normal life&quot;. The thing is that is not always the same, and I can speak a little bit from experience.&lt;/p&gt;
&lt;p&gt;When you include in the equation also people who had less opportunity, I came to the conclusion that there is a third type of mindset, one that I call the &lt;strong&gt;Resilient mindset&lt;/strong&gt;. This is a mindset that is built while facing daily challenges that are not common to many of Us. The biggest one is just being accepted for who you are or where you come from.
For example, those we call (naively) minorities, non binary people, or simply women in tech.&lt;/p&gt;
&lt;p&gt;I personally struggled to be accepted since I was in school because of where I come from, but I am still quite lucky because of my skin color and the fact that my country is located in the west side of the World. So I can only try to imagine what really feels like.&lt;/p&gt;
&lt;p&gt;IT is (in many people&apos;s mind, more than you think) a white male world. And like in the real world, we need to look at the real &lt;strong&gt;tangible results of years of this type of leadership&lt;/strong&gt;. And I&apos;ll be direct: &lt;strong&gt;We Fucked Up. Really bad.&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;From fake news, to rise of extremist to racism and supporting organizations who put children in cages, we have really really fucked up. We need a change, we need different people to take lead.&lt;/p&gt;
&lt;p&gt;White straight men like me (I will just refer to them as men for simplicity) have failed and, despite all the &quot;&lt;em&gt;N habits of successfull people&lt;/em&gt;&quot; and their &quot;&lt;em&gt;morning routines&lt;/em&gt;&quot;. The failure is so visible that even the other ones who fucked up greatly, the men in politics, are fed up with Us. We need &lt;strong&gt;people with the Resilient mindset&lt;/strong&gt; to take charge and lead.&lt;/p&gt;
&lt;h2&gt;They Have Skills that we don&apos;t have&lt;/h2&gt;
&lt;p&gt;Let&apos;s take women in tech for example. A woman who has reached a certain position and reputation is very (very very) likely to have had some situations in which she was less valuated, no matter what.&lt;/p&gt;
&lt;p&gt;The problem of a woman in tech is a problem that should have never existed in the first place, &lt;strong&gt;being accepted for who you are.&lt;/strong&gt; But it exists and it still shocks me to hear men talking about &quot;code has no gender or race&quot; when well ... you just need to look around you, the people you work with, to understand that there is, in fact, a problem.&lt;/p&gt;
&lt;p&gt;I am not a feminist and I am far from any extreme mentality or idealism, but this is a fact. &lt;strong&gt;,Coming out as gay takes courage&lt;/strong&gt;, being accepted as woman in tech takes &lt;strong&gt;courage&lt;/strong&gt;, going on stage and talking in front of hundreds of people, hoping that you will judged for your talk and skills and not because of your dress, that also takes courage.&lt;/p&gt;
&lt;p&gt;And with courage on facing those life challenges, you then build another skill, &lt;strong&gt;Empathy&lt;/strong&gt;. Those 2 skills alone are enough to make someone 10X smarter than many of those smart IT men that are clearly with a fixed mindset.&lt;/p&gt;
&lt;h2&gt;We fucked up, why not let them lead&lt;/h2&gt;
&lt;p&gt;I am working on a project with 2 women, I know that at least one of them had a lot of struggles to get accepted at work. Even though she is amazing in managing people, she could not get the chance she deserved.&lt;/p&gt;
&lt;p&gt;Some time ago, I asked her to take the lead as editor-in-chief of the project. Since then I have been staying behind the scene all this time. After an humble start, today we are having problem in managing all the emails of people who want to write for our magazine, the project is growing so much that we are literally building a community around it.&lt;/p&gt;
&lt;p&gt;I did not give the lead to her because &quot;she is a woman&quot;, I did it because I knew she just needed an opportunity. I know how good that person is at managing, and as a matter of fact, I was right.&lt;/p&gt;
&lt;p&gt;I simply made the math and realised that this person was the right one, and because of her struggle, I knew she had build enough resilience and empathy to make the project take the right direction.&lt;/p&gt;
&lt;p&gt;As humans our main instinct is still the same it was thousand of years ago, surving.&lt;/p&gt;
&lt;p&gt;Tech is an easy world ... for men. This is why is failing. We are not used to fight for surviving, no one will ask me, at a conference, if I work in HR or I am an office manager.
Getting your startup funded is not easy, but still how many startups and big companies are run by women?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In an environment where you don&apos;t need to fight for surving is hard to develop and improve your life skills, is just a fact.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is why so many become scared when a new change to the environment happens, because they know they don&apos;t have the skills to adapt (and compete) with these changes. Unlike those who, instead, have learned those survival skills.
The denial of climate change is a clear example of this, the &quot;code has no gender&quot; is another.&lt;/p&gt;
&lt;h2&gt;We need balance&lt;/h2&gt;
&lt;p&gt;When you look at any philosophy or religion, you will see that there is always a 2 side that balance each others, that&apos;s how the world works. Yin and Yang, good and evil, it does not matter. We need both for a balance. Even when we kill each other ... like in the wars ... Imagine for a moment if only one country had nuclear bombs during the cold-war ... Even in cases like this we need balance.&lt;/p&gt;
&lt;p&gt;In IT there is no balance. Elon, Mark, Jack, Jeff, Steve, you name it.
We have men who are being accused of sexual harrasment, or letting thousand of employees without a job. These people are &quot;forced&quot; to leave their companies ... with million of dollars in their accounts. This is not fair.&lt;/p&gt;
&lt;p&gt;The latest Nobel prize? Yeah ... &quot;.. And his wife&quot; ...
The woman who took a photo of a black hole? Ohh ... c&apos;mon it was a team work!
I&apos;d skip the politic part but look at all those blonde guys around.&lt;/p&gt;
&lt;p&gt;We fucked up so bad that really there are people who believe climate change is a hoax, and vaccines kill children, it&apos;s 2020 Jeez... We are going to spend billions to send people to Mars because we call it &quot;Evolution of men&quot;, while we keep immigrant in cages here on earth and people believe it&apos;s right.&lt;/p&gt;
&lt;p&gt;I hope things will change, I hope someone smart, who has skills, can take lead.
I hope more men will vote for women in politics, more gay people can have the freedom to live their lives,&lt;/p&gt;
&lt;p&gt;I hope one day this guy can go to his father and tell him that he is gay.
I hope my friend can become the manager that she deserves.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We cannot solve the problems with the same people that created them.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That is the main problem.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Horizontal Smooth Scrolling With CSS]]></title><description><![CDATA[While working on the redesign for this expats blog, I had to create a simple instagram carousel, the one that is in the footer.
It turns out…]]></description><link>https://www.antoniofullone.com/blog/horizontal-smooth-scrolling-css</link><guid isPermaLink="false">https://www.antoniofullone.com/blog/horizontal-smooth-scrolling-css</guid><pubDate>Thu, 31 Oct 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;While working on the redesign for this &lt;a href=&quot;https://www.thexpatmagazine.com&quot;&gt;expats blog&lt;/a&gt;, I had to create a simple instagram carousel, the one that is in the footer.
It turns out that is very simple to do it with some basic CSS.&lt;/p&gt;
&lt;p&gt;Here is the basic HTML:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;div class=&quot;carousel&quot;&gt;
  &amp;#x3C;div&gt;
    &amp;#x3C;img
      src=&quot;https://www.thexpatmagazine.com/static/da337e52c5c4fda4a74746c4dd0a583a/c47ac/73407466_813608455724510_1199731244955230163_n.jpg&quot;
      alt=&quot;The Expat Magazine in Instagram&quot;
    /&gt;
  &amp;#x3C;/div&gt;
  &amp;#x3C;div&gt;
    &amp;#x3C;img
      src=&quot;https://www.thexpatmagazine.com/static/c6dc076adea0a7330c996f0d014f8b15/c4d4c/75341471_400626140890704_8449279261212390382_n.jpg&quot;
    /&gt;
  &amp;#x3C;/div&gt;
  &amp;#x3C;div&gt;
    &amp;#x3C;img
      src=&quot;https://www.thexpatmagazine.com/static/bb15373ec0f09200ac64a39bf9813c47/7ed2b/69258652_194314211570668_674865124513666831_n.jpg&quot;
      alt=&quot;The Expat Magazine in Instagram&quot;
    /&gt;
  &amp;#x3C;/div&gt;
  &amp;#x3C;div&gt;
    &amp;#x3C;img
      src=&quot;https://www.thexpatmagazine.com/static/c20643536ef277a98ad3c52e7550ec49/7ed2b/69251740_149692732903083_5144742672846823710_n.jpg&quot;
    /&gt;
  &amp;#x3C;/div&gt;
  &amp;#x3C;div&gt;
    &amp;#x3C;img
      src=&quot;https://www.thexpatmagazine.com/static/c6dc076adea0a7330c996f0d014f8b15/c4d4c/75341471_400626140890704_8449279261212390382_n.jpg&quot;
    /&gt;
  &amp;#x3C;/div&gt;
  &amp;#x3C;div&gt;&amp;#x3C;/div&gt;
&amp;#x3C;/div&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Set the container to &lt;code&gt;display: flex;&lt;/code&gt;, &lt;code&gt;nowrap&lt;/code&gt; and with &lt;code&gt;overflow: scroll&lt;/code&gt; so that now we can scroll horizontally.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-css&quot;&gt;/* The container */

.carousel {
  display: flex;
  flex-wrap: nowrap;

  width: 100%;
  max-width: 320px;
  height: 200px;
  overflow: scroll;

  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We improve the scrolling with &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/behavior&quot;&gt;scroll-behavior: smooth&lt;/a&gt; and then we set the &lt;code&gt;scroll-snap&lt;/code&gt; on the X axis. As for the MDN website&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The visual viewport of this scroll container will rest on a snap point if it isn&apos;t currently scrolled. That means it snaps on that point when the scroll action finished, if possible. If content is added, moved, deleted or resized the scroll offset will be adjusted to maintain the resting on that snap point.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Basically we just snap the element to their container (try scrolling and see how it snaps to the left side of the carousel). Then in the child element:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-CSS&quot;&gt;.carousel &gt; div {
    flex: 0 0 auto;
    max-width: 320px;height: 100%;
    scroll-snap-align: start;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;flex: 0 0 auto;&lt;/code&gt; sizes the element based on its &lt;code&gt;width/height&lt;/code&gt;, or the width and height of their container. This is why I am setting the &lt;code&gt;max-width&lt;/code&gt; to 320px (just to set a minimum value).&lt;/p&gt;
&lt;p&gt;Finally we simply make the image a bit better responsive (In the blog I am using Gatsby Image for rendering a responsive image).&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-CSS&quot;&gt;.carousel img {
    max-width: 100%;
    width: 100%;
    height: 100%;
    object-fit: cover;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since we have set a fixed height for the carousel and that the image container has a height of &lt;code&gt;100%&lt;/code&gt;(height in percentage of an element works on if their parent has a defined height) we can use &lt;code&gt;object-fit&lt;/code&gt; to make the image fit the container width without looking stretched. Finally since we set the object-fit property, then we need to set the height to be &lt;code&gt;100%&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now we have a very simple, practical and quick Horizontal scrolling carousel.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://codepen.io/antoniofull/pen/BaamLzz&quot;&gt;Here is the codepen&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[ReactJs State and UI components]]></title><description><![CDATA[ReactJs (or React for brevity) is the most popular JavaScript UI Library out there. One of the feature that made React so popular and pushed…]]></description><link>https://www.antoniofullone.com/blog/understanding-state-in-react-js</link><guid isPermaLink="false">https://www.antoniofullone.com/blog/understanding-state-in-react-js</guid><pubDate>Wed, 30 Oct 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;ReactJs (or React for brevity) is the most popular JavaScript UI Library out there. One of the feature that made React so popular and pushed for his adoption is the so-called &lt;em&gt;Virtual DOM&lt;/em&gt;. A virtual DOM is a tree that represent the actual elements in the DOM, each element in this tree is a React Component which might or might not contain data. ReactJs knows which element had changed its data and renders in to the DOM only those elements.&lt;/p&gt;
&lt;p&gt;Understanding how this &lt;code&gt;data&lt;/code&gt; can be manipulated in React is important as each re-render (and so the perfomance) are connected to it.&lt;/p&gt;
&lt;h2&gt;React Components and Data&lt;/h2&gt;
&lt;p&gt;In ReactJs we have 2 different types of data&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Props. Data passed from some other component. This data is immutable, we cannot mutate props.&lt;/li&gt;
&lt;li&gt;State. Internal data manipulated by the component.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Props are just read only values that are passed to the component. We can only read them. So I will focus on React &lt;code&gt;state&lt;/code&gt; for this article.&lt;/p&gt;
&lt;h2&gt;Different Types of State in React&lt;/h2&gt;
&lt;p&gt;When working with UI components and React we can have 2 type of state:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Local State&lt;/em&gt;. Data manipulated directly by the component&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Global State&lt;/em&gt;. Data shared by several components. E.G: MobX/Redux or the Context API.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;React gives us a method called &lt;code&gt;setState&lt;/code&gt; for manipulate data inside the components, we also have hooks but we will look at this later.
State is also immutable, it means that each time we call &lt;code&gt;setState&lt;/code&gt; we should return a new object:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-JSX&quot;&gt;
this.setState({
  // Creates a new object merging old state and new values
  ...this.state,
  stateProp: newValue
});

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Local State&lt;/h3&gt;
&lt;p&gt;Local state is data manipulated directly by the Component. A component that does not uses state is called (guess what?) stateless component :)
When working with classes our state is managed inside the class with &lt;code&gt;this.state&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-JSX&quot;&gt;class Search extends Component {
    constructor(props) {
        super(props);
        this.state = {
            isSearchVisible: false,
        };

        this.toggleSearch = this.toggleSearch.bind(this);
    }

    toggleSearch(e) {
        e.preventDefault();
        this.setState({
            ...this.state,
            isSearchVisible: !this.state.isSearchVisible
        })
    }


    render() {
        const { isSearchVisible } = this.state;

        return (
            &amp;#x3C;Search&gt;
                &amp;#x3C;SearchButton onClick={this.toggleSearch} &gt;
                &amp;#x3C;SearchInput visible={isSearchVisible}&gt;
            &amp;#x3C;/Search&gt;
        )
    }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This state is local to the search component, but this is also a lot of boilerplate for simply clicking a button and I am not a big fan of classes.
We can simplify this code using function components and hooks:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-JSX&quot;&gt;function Search() {
    const [isSearchVisible, toggleSearch] = useState(false);

    const toggleSearch = e =&gt; {
        e.preventDefault();
        toggleSearch(!isSearchVisible);
    }

    return (
        &amp;#x3C;Search&gt;
            &amp;#x3C;SearchButton onClick={this.toggleSearch} &gt;
            &amp;#x3C;SearchInput visible={isSearchVisible}&gt;
        &amp;#x3C;/Search&gt;
    )
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the previous example I used for the local state, the &lt;code&gt;SearchInput&lt;/code&gt; is depending on the &lt;code&gt;Search&lt;/code&gt; component to be visible. We could abstract the logic in a hook to reduce even more the code.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-JSX&quot;&gt;
function useVisibilityToggle(isVisible = false) {
    const [visible, toggle] = useState(isVisible);
    const onToggle = () =&gt; {
        toggle(!visible)
    };

    return [visible, toggle];

}

// Use the new Hook

function NewComp() {
    const [visible, onToggle] = useVisibilityToggle(false);

    return (
        &amp;#x3C;NewContainer&gt;
            &amp;#x3C;Button onClick={onToggle} &gt;
            &amp;#x3C;SearchInput visible={visible}&gt;
        &amp;#x3C;/NewContainer&gt;
    )
}


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we can reuse it at least more easily among our components, making it a bit easier to use it with few extra lines.&lt;/p&gt;
&lt;h3&gt;Global State&lt;/h3&gt;
&lt;p&gt;Global state is state that is shared among different components (not necessarily in the same hierarchy or nested). There are several libraries like Redux or MobX for global state management but React has also its own API, the Context API. Libraries add obviously a lot of boilerplate code and are useful for managing large objcts (state is always a single object) while the Context API are good enough for handling simple primitive values, like for example a &lt;code&gt;dark theme&lt;/code&gt; or the language.&lt;/p&gt;
&lt;p&gt;I won&apos;t go in details with the libraries, as there are tons of tutorials for learning how to use them, but let&apos;s look at how we can handle global state with the React API.&lt;/p&gt;
&lt;h3&gt;Context API&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-JSX&quot;&gt;
const ThemeContext= React.createContext(&apos;dark&apos;);

// Set a display name property for our context
// So we can debug it in dev tools

ThemeContext.displayName = &apos;Theme&apos;;

function Component({children}) {
    return (
        &amp;#x3C;ThemeContext.Provider value=&quot;dark&quot;&gt;
            {children}
        &amp;#x3C;/ThemeContext.Provider&gt;
    );
}

function SubComponent() {
    return (
        &amp;#x3C;ThemeContext.Consumer value=&quot;dark&quot;&gt;
            {
                value =&gt; (
                    &amp;#x3C;Modal style={value} /&gt;
                )
            }
        &amp;#x3C;/ThemeContext.Consumer&gt;
    );
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;Modal&lt;/code&gt; component will render the dark or light style, depending on what is passed. We can update this value:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-JSX&quot;&gt;
function SubComponent() {
    const [isDarkTheme, setTheme] = useState(false);

    const toggleDarkTheme = () =&gt; {
        setTheme(!isDarkTheme);
    }
    const theme = isDarkTheme ? &apos;dark&apos; : &apos;light&apos;;
    return (
        &amp;#x3C;&gt;
        &amp;#x3C;Button onClick={toggleDarkTheme}&gt;
        &amp;#x3C;ThemeContext.Consumer value={theme}&gt;
            {
                value =&gt; (
                    &amp;#x3C;Modal style={value} /&gt;
                )
            }
        &amp;#x3C;/ThemeContext.Consumer&gt;
    );
}

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;When To Use Global State&lt;/h2&gt;
&lt;p&gt;Generally speaking, in JavaScript everything that is global is considered bad as it carries always side-effects. React is based on the concept of splitting our UI in components and making those components rely on global state might not be the best solution. Obviously there are exceptions, a state for a user if is loggedin or a language variable, or the theme example I used above. Those are all cases when we can use global state.&lt;/p&gt;
&lt;p&gt;But as a general rule, especially with new additions like hooks I think there are less and less case for using global state. A design system and its component should not depend on external state, unless is really inevitable.&lt;/p&gt;
&lt;p&gt;Reference and Reading List:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://reactjs.org/docs/hooks-intro.html&quot;&gt;React Hooks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://reactjs.org/docs/context.html&quot;&gt;React Context API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://redux.js.org/&quot;&gt;Redux&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/mobxjs/mobx-react&quot;&gt;MobX&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Is always sunny in Calabria]]></title><description><![CDATA[When I went to Cuba, my first impact with the city, Havana, was shocking. It is incredible how these people live in poverty and, at the same…]]></description><link>https://www.antoniofullone.com/blog/is-always-sunny-in-calabria</link><guid isPermaLink="false">https://www.antoniofullone.com/blog/is-always-sunny-in-calabria</guid><pubDate>Sat, 14 Sep 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;When I went to Cuba, my first impact with the city, Havana, was shocking. It is incredible how these people live in poverty and, at the same, they still enjoy life.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;We have food for today, my children are healthy and I have a roof under my head, that&apos;s all I need for me and my family.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This was the answer from a woman I was talking to. After the talk, she took an old radio, like the ones we used in the &apos;90s and put some salsa music.&lt;/p&gt;
&lt;p&gt;After a few minutes, everyone around came and joined us dancing in the street (well I wasn&apos;t really dancing but .. I was there). Cuban people are happy despite all their problems.&lt;/p&gt;
&lt;p&gt;I grew up in Calabria, one of the poorest regions in the so-called developed world. I am lucky enough to have a job, and I have a salary that is much higher than the average salary in Calabria.&lt;/p&gt;
&lt;p&gt;Yet here people are happy too. Of course, we complain about the government and the politicians, but people can still enjoy life.
Calabria is a beautiful but we are famous only for our &lt;strong&gt;&apos;ndrangheta&lt;/strong&gt;, or if sounds more familiar, &lt;strong&gt;mafia&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Cuban and Calabrian have one thing in common, &lt;strong&gt;we are both used to be forgotten by the rest of the world&lt;/strong&gt;. We are used to living like this. We are used to be the last.&lt;/p&gt;
&lt;p&gt;Many of my friends would not be able to live in a place like Milan or London, they would end up depressed in less than a year.
I could not stand anymore living in the Netherlands after 4 years. I missed the sun, the beaches, and the people smiling.&lt;/p&gt;
&lt;p&gt;Before leaving I had a job offer from a company who was just acquired by eBay. I rejected it, and instead, I accepted a job in Gibraltar, so that I could live in Andalusia, which is very similar to my region.&lt;/p&gt;
&lt;p&gt;I thought a lot about this episode. Many people told me that I was crazy to reject it, that Amsterdam was the best place in Europe for working in IT (it&apos;s true, it is) and that I screwed my career because of that.&lt;/p&gt;
&lt;p&gt;I still think about it from time to time but I have no regrets. Some people spend their lives working hard to get their promotion, save money for retirement and get burnout after 5 years. Because this is what they are taught.&lt;/p&gt;
&lt;p&gt;I knew since I was a kid that I would not have the same opportunity as anyone else, I knew that if I wanted to have something in my life, I had to work harder than anyone.&lt;/p&gt;
&lt;p&gt;I did, and despite everything, I checked many of my &lt;strong&gt;&quot;life to-do list&quot;&lt;/strong&gt; items. But I also let go some of them, when I realized that they would not make me happy.&lt;/p&gt;
&lt;p&gt;Because I was born in Calabria, and here we see happiness differently. We keep smiling and helping each other no matter what. This is the beauty of my region, and this is why I am proud to say I was born there.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[My coding and travel setup]]></title><description><![CDATA[Today I am going to share the tools I use for work and for my (movable) studio. I have been working remotely since 3 years, and mostly…]]></description><link>https://www.antoniofullone.com/blog/coding-travel-setup</link><guid isPermaLink="false">https://www.antoniofullone.com/blog/coding-travel-setup</guid><pubDate>Thu, 23 May 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Today I am going to share the tools I use for work and for my (movable) studio. I have been working remotely since 3 years, and mostly living in Airbnb and friends/family&apos;s couches, so my setup might be quite different than many others.
There are some referral links to this article, so be aware of that.&lt;/p&gt;
&lt;h2&gt;Hardware&lt;/h2&gt;
&lt;p&gt;I bought my first MacBook in 2005 and since then I always used only Mac. Last year I bought a MacBook pro 15&apos;&apos; with touch bar and, let me say it loudly, &lt;strong&gt;&lt;em&gt;it is the worst laptop I ever had.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The touch bar is completely useless and also it annoys me a lot. Especially when I hit the delete key and I also touch the bar which will turn off the sounds ... But this is not the real problem, as it is very well known, the keyboard is incredibly bad ...
I have lost the &quot;e&quot;, &quot;command&quot;, &quot;r&quot;, &quot;d&quot; and many others. They are still on the keyboard but it is a real pain typing it, since they fall apart easily, and since where I am living now there are no apple stores ... it is even worse.&lt;/p&gt;
&lt;p&gt;Let&apos;s skip the battery, which since I bought lasts more or less 1 hour if I am not running any nodejs or Xcode process. I am planning to buy a new laptop, but without touch bar and, probably also smaller.&lt;/p&gt;
&lt;p&gt;I also have an &lt;strong&gt;iPhone 7, iPhone 5, IWatch 2 and an Ipad mini.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;While I still love apple, the security, the User Experience, and the design in general, I cannot understand what is wrong with their engineer. It seems that they are not able to release a single device that can have decent battery life. That means I also have 2 portable USB chargers always with me.&lt;/p&gt;
&lt;p&gt;I don&apos;t have a second screen but I do have a USB-C HDMI adapter and I usually connect to either a tv or screen if necessary.&lt;/p&gt;
&lt;p&gt;At home I keep the old MacBook 2006 that I bought (Still working as long as is connected to the charger), a second screen, a laser printer (connected to the cloud too) and a very simple desk.&lt;/p&gt;
&lt;p&gt;When I traveled to Canada I bought also the &lt;strong&gt;Bose headphones quite comfort 15&lt;/strong&gt;, they are not wireless but I also bought a Bluetooth adapter so I can use it without wires. I have the original iPhone&apos;s headphones.&lt;/p&gt;
&lt;p&gt;I have a 2 Terabyte external hard disk and some USB sticks, just for an emergency but I do not put work or important data on these physical devices. I have a &lt;strong&gt;Dropbox&lt;/strong&gt; account with about 10GB and paid ICloud subscription for saving all my photos and files, safely. Since I do not use social networks, Icloud is where I store basically all my life events, photos, and travels.&lt;/p&gt;
&lt;h2&gt;Coding&lt;/h2&gt;
&lt;p&gt;I use &lt;strong&gt;Visual Studio Code&lt;/strong&gt; with a few extensions, mostly code highlighting for Javascript, React and GraphQL, plus Emmet. Eslint and some nice React/React Native snippets.&lt;/p&gt;
&lt;p&gt;I have installed also the browser preview extension, but to be honest I mostly use the browser.I use the dark+ theme and &lt;strong&gt;vs-seti&lt;/strong&gt; for the icons. The font is &lt;a href=&quot;https://fonts.google.com/specimen/Inconsolata&quot;&gt;Inconsolata&lt;/a&gt; set to 16px.&lt;/p&gt;
&lt;p&gt;I use &lt;strong&gt;Vim&lt;/strong&gt;, mostly in the terminal, but I also use &lt;a href=&quot;https://github.com/macvim-dev/macvim&quot;&gt;Mac Vim&lt;/a&gt;, which is very handy. In order to use Vim properly, because of the touch bar, I mapped the Caps Lock button to Esc, so now every time I have to WRITE IN CAPS, I must hold the shift button. If you use Vim you know how important is the Esc Key ...&lt;/p&gt;
&lt;p&gt;I switched recently to &lt;a href=&quot;https://hyper.is/&quot;&gt;Hyper&lt;/a&gt; for the terminal, I used Iterm for several years, but I decided to change.&lt;/p&gt;
&lt;p&gt;For &lt;strong&gt;Git&lt;/strong&gt; I recently switch between using the terminal and the github desktop app. But at work, we actually do not use (just) github, so I still use the terminal for most of the repo&apos;s work. And I like it. I do have few &lt;strong&gt;git aliases&lt;/strong&gt; setup too.&lt;/p&gt;
&lt;p&gt;While I use Safari for personal browsing, I use Chrome and Firefox for work. Chrome we know is great (although it eats so much ram ... ) but &lt;strong&gt;Firefox&lt;/strong&gt; has become (again) incredibly good and fast, and boy ... the CSS grid in the inspector panel is much better than chrome. I would say also for CSS in general.&lt;/p&gt;
&lt;p&gt;I use &lt;a href=&quot;https://macdown.uranusjr.com/&quot;&gt;MacDown&lt;/a&gt; for writing posts and for markdown in general, is a very easy app with preview and it gets the job done.&lt;/p&gt;
&lt;p&gt;Not related to coding, but I also use &lt;strong&gt;Clean My Mac&lt;/strong&gt;, which is great especially for deleting the many cache files that mac creates. It saves me every time also from restarting the laptop.&lt;/p&gt;
&lt;p&gt;An interesting app that I discovered recently is &lt;a href=&quot;http://open-indy.github.io/Koa11y/&quot;&gt;&lt;strong&gt;Koa11y&lt;/strong&gt;&lt;/a&gt; which is basically like Google lighthouse but for accessibility.&lt;/p&gt;
&lt;p&gt;Finally, I use &lt;strong&gt;Transmit&lt;/strong&gt; for ftp related stuff.&lt;/p&gt;
&lt;h2&gt;Design&lt;/h2&gt;
&lt;p&gt;I use to have a &lt;strong&gt;Photoshop&lt;/strong&gt; license but I let it expire this year. I use &lt;strong&gt;Sketch App&lt;/strong&gt; for designing UI and for Mockups, while at work we use &lt;strong&gt;Figma&lt;/strong&gt;, which is pretty great. I still have to learn a lot about it, mostly because for prototyping I always used ADOBE XD or Sketch. So I have to get used to Figma soon.&lt;/p&gt;
&lt;p&gt;I used a lot &lt;strong&gt;Illustrator&lt;/strong&gt;, mostly for designing Icons or just some art, and I will probably re-buy it again, as I don&apos;t see Sketch better than Illustrator for design. Sketch is mostly UI oriented but Illustrator is another thing when it comes to just design.&lt;/p&gt;
&lt;p&gt;I design my &lt;strong&gt;own invoices&lt;/strong&gt;, nothing fancy but I don&apos;t use any software and I have a Sketch template that I fill every time I have to make an invoice and then export it as PDF. As for the photos I keep everything on Icloud and, some parts, also in Dropbox.&lt;/p&gt;
&lt;p&gt;I use &lt;strong&gt;Mindnode&lt;/strong&gt; for basic mind mapping for designs, ideas, apps, websites.&lt;/p&gt;
&lt;p&gt;I use &lt;strong&gt;ImageOptim&lt;/strong&gt; and &lt;strong&gt;JPEG&lt;/strong&gt; mini for optimizing images, whenever I need it. I use some online services for SVG&apos;s cleaning.&lt;/p&gt;
&lt;p&gt;I have always with me my &lt;strong&gt;Moleskine&lt;/strong&gt;, where I take notes or sketch some ideas. I really like creating my to-do lists on post-it. The idea behind is that having small post-it it makes the list short and it feels quite rewarding when I simply close all the task on one post it and then I trash the paper away.&lt;/p&gt;
&lt;p&gt;I use also &lt;strong&gt;Todoist&lt;/strong&gt; and &lt;strong&gt;Focus&lt;/strong&gt; for managing my time and tasks (beside Jira and the normal bugs traker) while for a personal project with a small team we use Trello.&lt;/p&gt;
&lt;h2&gt;Travel&lt;/h2&gt;
&lt;p&gt;This isn&apos;t really a setup but as a remote worker and avid traveler I really need to also have my own setup here. In the last 3 years, I travelled with a small trolley and a big Carpisa luggage. Yes, my entire life fits in 2 luggage, not kidding.
I have my backpack bought on Amazon for 29 Euros, with USB connector for recharging the phones and anti-thief protection. Oh ... it has also a nice cover for when it is raining.&lt;/p&gt;
&lt;p&gt;As a backup for internet, I use &lt;a href=&quot;http://skyroaminc.refr.cc/LNQFP7Q&quot;&gt;&lt;strong&gt;Skyroam&lt;/strong&gt;&lt;/a&gt; (ref link), but thanks to the European Union law on roaming I can also use one of my phones, although not ideal it works in emergency cases. Most of my work involves coding and pushing to repo&apos;s so few gigabytes are enough. Skyroam is great but it costs really a lot of money, 8 dollars a day, and you only get up to (I think) 500 MB. So not that much.&lt;/p&gt;
&lt;p&gt;I have a &lt;a href=&quot;https://revolut.com/r/antoninlx&quot;&gt;&lt;strong&gt;Revolut card&lt;/strong&gt;&lt;/a&gt; (ref link) connected to my main credit card and bank account. I can recharge it on the fly and it comes with few nice advantages.
I can withdraw for free in any ATM worldwide up to a certain amount(Italian and Spanish banks always charge some fees), but more important I can exchange currencies in real time and, almost, at the real exchange rate. This makes me save quite a lot while traveling, as I did when I was in North America last year.
Another great feature of Revolut is that I can create virtual cards that I can use online and then delete it, avoiding some extra risks online.&lt;/p&gt;
&lt;p&gt;I use also &lt;a href=&quot;https://transferwise.com/i/antoniof3&quot;&gt;Transferwise&lt;/a&gt; (Ref link) as it is very handy for transferring money in different currencies.&lt;/p&gt;
&lt;p&gt;I have a KLM, Iberia and Alitalia miles card. You don&apos;t get many miles while traveling in Europe but, in the last 6 years, I got 3 free flights thanks to miles. (I flew in North and South America too).&lt;/p&gt;
&lt;p&gt;I use &lt;strong&gt;Uber, MyTaxi and Google Maps&lt;/strong&gt; for transportation.&lt;/p&gt;
&lt;p&gt;Whenever I choose a place to travel, the first things I check is a co-working place. Is a good place to meet new people, but also very useful for fast internet, printing and meetings.&lt;/p&gt;
&lt;p&gt;I usually book either with &lt;a href=&quot;https://abnb.me/e/It2rXODSUW&quot;&gt;&lt;strong&gt;Airbnb&lt;/strong&gt;&lt;/a&gt; (ref link) or &lt;strong&gt;Booking.com&lt;/strong&gt; and obviously, I always check for the wifi first.&lt;/p&gt;
&lt;p&gt;Airbnb can be tricky as many pieces of informations about the place are shared only after booking, and sometimes the hosts have limited wifi or a single wifi connection working for several apartments. &lt;em&gt;Be aware that this is a pretty common tactic&lt;/em&gt; in several places in Europe.&lt;/p&gt;
&lt;p&gt;I have a &lt;strong&gt;Kindle&lt;/strong&gt; and I switch, for reading, between the Kindle and the Kindle app on my Ipad mini, but I prefer Kindle mostly because is the original Kindle, so no extra software or distracting tools.&lt;/p&gt;
&lt;p&gt;I also have always with me my favorite book, a real physical book. For me is just more than a book, is like a bible and every page or line in that book is an inspiration. I am talking about &lt;strong&gt;Meditations&lt;/strong&gt; by Marcus Aurelius.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Singly Linked List with Javascript]]></title><description><![CDATA[When working with data in Javascript we usually rely on arrays and objects as primary way to store data. There are in fact a lot of…]]></description><link>https://www.antoniofullone.com/blog/data-structures-with-javascript-singly-linked-list</link><guid isPermaLink="false">https://www.antoniofullone.com/blog/data-structures-with-javascript-singly-linked-list</guid><pubDate>Tue, 23 Apr 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;When working with data in Javascript we usually rely on arrays and objects as primary way to store data. There are in fact a lot of different way to structure our data and each one of them has some pros and cons and a practical usage. Linked List are a type of data structure that isn&apos;t talked too much and, especially when it comes to interview, seems to be a topic quite scaring.&lt;/p&gt;
&lt;p&gt;I am not entering into the discussion of the algorithm/data structure interview for a FrontEnd (there is enough fire out there about it), but Linked List can be pretty useful compared to array, and they have a lot of advantages.&lt;/p&gt;
&lt;p&gt;All the code is available on &lt;a href=&quot;https://github.com/antoniofull/javascript-data-structures/blob/master/src/SinglyLinkedList.js&quot;&gt;github&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;What are linked list?&lt;/h2&gt;
&lt;p&gt;Linked list is a very simple type of data structure where each Node has a pointer to the next node.&lt;/p&gt;
&lt;p&gt;A linked list is formed by 4 elements:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Nodes&lt;/strong&gt;, an object that contains the value and the pointer to the next element.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Head&lt;/strong&gt; The first Node of the list&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tail&lt;/strong&gt;, The last Node of the list. This object as a property next that is set to null&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Length&lt;/strong&gt; (or Size) the lenght of the list.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;How Linked List differ from Array&lt;/h2&gt;
&lt;p&gt;Linked List have no indexes. You cannot do &lt;code&gt;MyLinkedList[1]&lt;/code&gt; to get your item (we will implement our own method for it), but this is a good think because it makes insertion and deletion very fast compared with Array, this is because we don&apos;t need to re-index the list.&lt;/p&gt;
&lt;p&gt;Array are of a fixed size while Linked List are dynamic in size. If this is not clear look at this image.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/posts/list-vs-array.png&quot; alt=&quot;Linked List vs Arrays&quot;&gt;&lt;/p&gt;
&lt;p&gt;The orange slots are the one occupied by the array. Once we declare our array &lt;code&gt;const arr = [1,2,3,4,5]&lt;/code&gt; a slot of memory is assigned to this data. You can see that the slots occupied by the array are contiguous. If you look at the blue one, taken by the linked list, we can see instead that is dynamic, because each node is going to take his own space, and we jut have pointers.&lt;/p&gt;
&lt;p&gt;The red slots indicateds a slot that is already occupied, at this point if we add a new item to the array the entire array will have to be relocated in memory, while with a Linked List the next added node it will just take the next available slot.&lt;/p&gt;
&lt;p&gt;It might seems confusing but in fact you don&apos;t need to know all this memory stuff, it&apos;s just good to know what is the main difference with Arrays. So to recap:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Linked List are better for quick insertion and deletion. If you have to do this often, a linked list is much efficient than an array.&lt;/li&gt;
&lt;li&gt;Linked List are dynamic in size, array are fixed. This does not mean it is always an advantage because it also means that it is using more memory (is a little trade off, like with recursions).&lt;/li&gt;
&lt;li&gt;Arrays are better at random access&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;So when to use a Linked List?&lt;/h2&gt;
&lt;p&gt;If you do very often insertion and deletion of element, then go for a Linked List.
If you need often random access go for an array
If you need to traverse the data often, then again array is a better solution.&lt;/p&gt;
&lt;h2&gt;Practical Use for Linked List&lt;/h2&gt;
&lt;p&gt;If you think about it, a Linked List is basically a Node that points to another node (the next) but cannot go back (there are Doubly Linked List for this), it can grow dynamically and it has a start and a end (head and tail). This makes it perfect for example for a Learning Path or a Lesson Plan.
Once you attended lecture one, then the next step might only lecture two, and so on.&lt;/p&gt;
&lt;p&gt;Also, level of videogames can be seen as Linked List, you play on the first level once you finish that level you can only go to the next one.&lt;/p&gt;
&lt;p&gt;These are some of the example that just came in my mind right now, I am sure that there are a lot more.&lt;/p&gt;
&lt;h2&gt;Let&apos;s build our own linked list&lt;/h2&gt;
&lt;p&gt;So I think it&apos;s about time to start coding something and build our own Linked List. Here some notes to consider:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Naming&lt;/strong&gt;: Linked List, unlike arrays have no built-in methods, that means we have to build our own. For simplicity I will try to use the same naming as array. but this is not a rule. For example I like to call the method to remove the Tail (last element of the list) pop, like array. But you could call it &lt;code&gt;removeTail&lt;/code&gt;. I prefer pop because in fact we do not remote the tail, the previous Node will be our new tail.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Coding Style&lt;/strong&gt;: I am using ES6 classes, just to make the readability a bit easier. You can use function if you want, in the end this is what a ES6 class is so feel free to use whatever you want.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Comments&lt;/strong&gt;: While learning these data structures commenting my code very often helped me to better remember what I did when I came back to it after some months :D Anyway, I am just warning you that I will add a lot of comment, hoping this will help to better understand what is going on.&lt;/p&gt;
&lt;p&gt;First we build our Node and then our SinglyLinkedList Class:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;/** Class representing a Node */

// We create the Node

class Node {
  constructor(val) {
    // Initialize the node with the val passed
    // And set the next pointer to null
    this.val = val;
    this.next = null;
  }
}

/* Singly List Class */

class SinglyLinkedList {
  constructor() {
    // Initialize with the basic 3 elements of the list
    // Head, Tail, Length.

    this.head = null;
    this.tail = null;
    this.length = 0;
  }
}

// Initialize List

const List = new SinglyLinkedList();
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Is Empty Method&lt;/h3&gt;
&lt;p&gt;We will often need to check if our linked list is empty. We can use one of the 3 main elements of the list to verify if empty and return either true or false. Let&apos;s add this little helper then&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;	/**
   * Check if the list is empty
   * @return {Boolean}
   */

	isEmpty() {
	// If no head or length is 0
	// return null/false
    return !this.head || this.length === 0;
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we have a Node class and out SinglyLinkedList class, we can now add our first 2 methods. We can start with removing the head and the tail. For this we need 2 methods:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Shift&lt;/strong&gt; - Removes the first element, the head&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pop&lt;/strong&gt; - removes the element at the end of the list, the tail&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Shift Method&lt;/h3&gt;
&lt;p&gt;Let&apos;s look first at the logic for removing the head. First we look at the edge cases:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Is the list empty?&lt;/li&gt;
&lt;li&gt;Is the Head also the only node in the list? (if so it means is also the tail)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;After considering these 2 cases we know now that the head exists and it has a next Node, which is going to be our new Head. So it&apos;s just a matter of setting head.next to be the new head.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;  /**
   * Removes head and set next Node to be the new head
   * @return {Node} the removed Node
   */
  shift() {
    // Edge case 1: List is empty
    if(this.isEmpty()) return null;
    // Store a reference to the removed node
    const removedHead = this.head;
    // Set next to be the new head
    this.head = this.head.next;
    // decrease length
    this.length--;
    // Edge case 2: Head was the only node
    if(this.length === 0) {
      this.tail = null;
    }
    // Return the removed Head
    return removedHead;

  }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I hope the comments are clear. This is pretty easy, we just have to be careful with the edge cases.&lt;/p&gt;
&lt;h3&gt;Pop Method&lt;/h3&gt;
&lt;p&gt;Popping a node from the list, in this case the tail, is a little bit different than removing the head. In this case we need to traverse the list until we reach the end, the tail, we need a reference to the previous node wich will be our new tail.
Always remember the edge cases.
The steps are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Verify if list is empty&lt;/li&gt;
&lt;li&gt;If list has only one node, then tail and head are the same, we set them to null and we return the removed node&lt;/li&gt;
&lt;li&gt;If none of the above we loop through the list using a reference to the next pointer.&lt;/li&gt;
&lt;li&gt;If node.next is null we reached the end&lt;/li&gt;
&lt;li&gt;Now we have a reference to the node previous to the tail, we set the tail to be this node.&lt;/li&gt;
&lt;li&gt;Set tail.next to be null&lt;/li&gt;
&lt;li&gt;Decrease Length&lt;/li&gt;
&lt;li&gt;Return removed tail&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;// Check if list is empty
if (this.isEmpty()) return undefined;

// If there is only one Node
// Then we can just set head and tail to null
// And return the tail
if (this.length === 1) {
  const tail = this.tail;
  this.head = this.tail = null;
  this.length--;
  return tail;
}

// We must traverse the list
// Starting from the head
// So we get a reference to the list
let current = this.head;
// Because Singly Linked List cannot go backward
// We need a reference for what it will ne the new tail, the last node in our loop
let newTail = current;
// The tail has next null
// So the loop stops when we reach the tail
while (current.next) {
  // the newTail keeps following the current node in the loop
  newTail = current;
  // We move on to the next pointer
  current = current.next;
}

// We reached the end of the list
// newTail is now the last item
// So the tail
this.tail = newTail;
// Cut out the next Node
// So tail.next = null
this.tail.next = null;
// Decrease the length
this.length--;

// Return the node we just removed
return current;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Unshift Method&lt;/h3&gt;
&lt;p&gt;Now we want to add a new Node that will be the new head, so like in array we want to have a unshift method that adds his node to the beginning of the list.
Here is where Linked List really shine and win easily. What we have to do is just to set the new node to be the head and the head to be the next of this node.
Steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a new node from the value passed&lt;/li&gt;
&lt;li&gt;Check if list is empty. If so, then head and tail are the new node&lt;/li&gt;
&lt;li&gt;If not empty set new node.next to the the head&lt;/li&gt;
&lt;li&gt;Set node to be the new head&lt;/li&gt;
&lt;li&gt;Increased Length&lt;/li&gt;
&lt;li&gt;Return the new list&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Remember that all this methods works in place, we are mutating the list in place.&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;
	/**
	 * Adds a new Node at the beginning of the list
	 * The new node is now the head
	 * @param val - the Node value
	 * @return {SinglyeLinkedList}
	 */

	unshift(val) {
		// create the node
		const node = new Node(val);
		// if list is empty set head and tail to be the new node
		if(this.isEmpty()) {
			this.head = this.tail = node;
		} else {
			// 3. Set node.next to be the head
			node.next = this.head;
			// 4. Set new head
			this.head = node;
		}

		// Increment the length
	    this.length++;
	    // Return the List
	    return this;
	}

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Push Method&lt;/h3&gt;
&lt;p&gt;Now we want to add a new item to the end, the tail. This is also very easy and fast. Here the steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a new Node&lt;/li&gt;
&lt;li&gt;Check if list is empty, set head and tail to be the same&lt;/li&gt;
&lt;li&gt;set actual tail.next to be the new node&lt;/li&gt;
&lt;li&gt;set the tail to be the new node&lt;/li&gt;
&lt;li&gt;increase length&lt;/li&gt;
&lt;li&gt;return list&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;
	  /**
	   * Adds a new Node at the end of the list
	   * The new node is now the tail
	   * @param val - the Node value
	   * @return {SinglyLinkedList}
	   */

	   push(val) {
	   	// 1. Create a new node
	   	 const node = new Node(val);

	   	// 2. If the list is empty then
       // then the new node is both the head and the tail
    if (this.isEmpty()) {
      // set both head and tail to be the node
      this.head = this.tail = node;
    }
	   } else {
	   	// 3. Set the next pointer of the actual tail to be the new node
      this.tail.next = node;
      // 4. Then set the new Node to be the tail
      this.tail = node;
	   }

	   // 5. Increase length
	   this.length++;

	   // 6. Return List
	   return this;
	}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ok, so now we have our basic methods. We now want to implement some helpful methods:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A Method to empty the list&lt;/li&gt;
&lt;li&gt;Traverse the list&lt;/li&gt;
&lt;li&gt;Search for an element in the list based on its index or value&lt;/li&gt;
&lt;li&gt;Update a node&lt;/li&gt;
&lt;li&gt;Insert new nodes at a certain index&lt;/li&gt;
&lt;li&gt;Reverse the list&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Empty the List&lt;/h3&gt;
&lt;p&gt;Let&apos;s start with the simple one. Empty the list&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;
	/**
   	* Empties the list
   	* @retun {SinglyLinkedList}
  	*/

	  emptyList() {
	    this.head = this.tail = null;
	    this.length = 0;
	  }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Self explanatory I would say.&lt;/p&gt;
&lt;h3&gt;Traverse the List&lt;/h3&gt;
&lt;p&gt;Traversing the list is easy, we just go to the next node &apos;till we hit null. This method might come handy for some next other methods. We can add a callback to the method, so that we can then reuse the value or node to do something. I&apos;ll call this method &lt;code&gt;run&lt;/code&gt;, I just like it more than &lt;code&gt;traverse&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;
	 /**
   * Traverse the entire Linked List
   * @callback cb - do something with the list
   * @Example
      function log(node) {
        if(node) {
          console.log(&apos;The value is: &apos;, node.val);
          if(!node.next) {
            console.log(&apos;we reached the end, &apos;, node.val)
          }
        }
      }
   *
   * */
  run(cb) {
    // Reference to the head
    let current = this.head;

    // Loop until we reach the end
    while (current) {
      // Do something with the value
      cb(current);

      // move on
      current = current.next;
    }
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can search in a Linked List either based on the index or the value. For the value is pretty easy to do.
Just loop through all the list until you find the value you are looking for.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;   /**
   * Find a Node in the list based on a value
   * @param val - the value to search in the list
   * @return the Node if found or false
   */
  find(val) {
    let current = this.head;
    // traverse the entire list
    // We could use also the run method and pass the
    // callback to it
    // But let&apos;s do it normally
    while (current) {
      if (current.val === val) {
        // we found the node
        return current;
      }
      current = current.next;
    }
    return false;
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now it&apos;s time to add a search method for the list. I am saying here search, but probably &lt;code&gt;findAt&lt;/code&gt; is a better name for the method. We pass the index and we return the node that we have found. As I explained before, we must loop through the list in order to find our node.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;
	/*
	* Search for a node in the list
	* @param {Number} index - the index of the node
	* @returns {Node} the node
	*/

	findAt(index) {
		// First we must be sure that the index is present in our list
		// We know that it cannot be negative and cannot be greater than the length of the list
		if(index &amp;#x3C; 0 || index &gt; this.length) {
			return null;
		}
		// let&apos;s create a variable to keep the count in the loop
		let count = 0;
		// We keep a reference to for looping starting from the head
		// Until we find our node
		let currentNode = this.head;
		// Loop until count is equal to index
		while(count !== index) {
			currentNode = currentNode.next;
			count++;
		}

		// We found our node and we return it
		return currentNode;
	}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It&apos;s time now to update a value. This is now really easy, we just created a &lt;code&gt;fintAt&lt;/code&gt; method that we can reuse here to get the element, using the index, and then we just need to update the value &lt;code&gt;val&lt;/code&gt;. The only check we have to do is to see if he value exists or not:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;
	/*
	* Update a node in the list
	* @param val - the new value for the node
	* @param {Number} index - the index of the node
	* @returns {Node} the node
	*/

	// Set the value on a certain index
	// I use set as name rather than update
      update(index, val) {
      // we take advantage of our findAt method
      let node = this.findAt(index);
      // If node is found
      if (node) {
        node.val = val;
        return node;
      }
      // Node not found
      return false;
    }

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Allright! So we get nodes, we update them we remove and add new nodes but only at the beginning and at the end, we want also to add an element at a certain index or remove it. So let&apos;s start with our insert method&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;
/*
* Insert a new node in to the list
* @param {Number} index - the index for the node
* @param val - the node&apos;s value
* @returns {Node} the newly added node
*/

insert(index, val) {
  // We first test if the index is valid in the list
  if (index &gt; this.length || index &amp;#x3C; 0) return false;
  // If the index is 0 then we are adding a new head
  // We can use the previous method unshift to do this
  if (index === 0) {
    return this.unshift(val);
  }
  // The index might also be the last item
  // Hence the tail. Again we can use one of the previous method
  // This time push as we add the node at the end of the array
  if (index === this.length) {
    this.push(val);
    return true;
  }
  // Create a new Node
  const node = new Node(val);


  // We find the node that precedes our new node
  let prev = this.get(index - 1);

  // We need to swap the values with our new node
  // let&apos;s use a tmp variable for it
  let tmp = prev.next;

  // Set next to be the new Node
  // Because index - 1 so we have to
  // add the node to the next
  prev.next = newNode;

  // set next from new inserted val
  // to be the temp we stored before
  newNode.next = temp;

  // We must increase the length
  this.length++;
  // Return true
  return true;
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This also should not really be hard to undertand. Basically what we do is that we add the new node at the index and we move the value that was at that index after.&lt;/p&gt;
&lt;p&gt;And now we can remove the node, this time we only need the index.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;/*
* Removes a node from the list
* @param {Number} index - the index for the node
* @returns {Node} the node that was removed
*/

remove(index) {

  // Again let&apos;s check if the index is valid
  if (index &amp;#x3C; 0 || index &gt; this.length) return false;

  // Or if index is the head or the tail
  if (index === 0) return this.shift();
  if (index === this.length - 1) {
    this.pop();
    return true;
  }

  // get the previous node
  let previousNode = this.get(index - 1);

  // The node after previousNode is our node
  // to be removed
  let removed = previousNode.next;

  // we set the previous node to be the next
  previousNode.next = removed.next;

  // decrease length
  this.length--;

  // return element
  return removed;
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;OK, so what is left now is to reverse the linked list. Reversing a linked list with Javascript seems also to be one of those hard interview questions. And, imo, the trickest part is just to understand what reversing a linked list really means.&lt;/p&gt;
&lt;p&gt;The first time I approached it, without looking at any tutorial, I made the mistake of thinking to it as an array. For example in an array you have this:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;[1,2,3,4,5]&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;And reversing it means to return this:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;[5,4,3,2,1]&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;With linked list is different. To better understand what it means, let&apos;s look at it visually:
You start with this:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;1-&gt;2-&gt;3-&gt;4-&gt;5-&gt;null&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;And you have to return this:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;null&amp;#x3C;-1&amp;#x3C;-2&amp;#x3C;-3&amp;#x3C;-4&amp;#x3C;-5&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;So basically that means:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;First we must swap head and tail, so our new head will be 5 and our tail will be 1&lt;/li&gt;
&lt;li&gt;Then we have to change the pointer, &lt;code&gt;node.next&lt;/code&gt;, to be the previous one.
you just need to point to next link,&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;There are 2 ways to reverse a Linked List. We can do it using a loop, a for loop or while lopp, or we can do it with recursion.&lt;/p&gt;
&lt;p&gt;Recursion is more elegant as solution, but it uses more memory because each time the function calls itself and it creates a new context.&lt;/p&gt;
&lt;p&gt;I also, honestly, get easily confused with recursions. I will do with both, first using a loop then using recursion.&lt;/p&gt;
&lt;p&gt;So the logic behind is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Swap head and tail&lt;/li&gt;
&lt;li&gt;Keep track of next node&lt;/li&gt;
&lt;li&gt;Keep track of previous node&lt;/li&gt;
&lt;li&gt;Set a node reference to the head&lt;/li&gt;
&lt;li&gt;Traverse the list using the node ref&lt;/li&gt;
&lt;li&gt;Set next to be node.next&lt;/li&gt;
&lt;li&gt;Set node.next to be the previous&lt;/li&gt;
&lt;li&gt;Set previous to be the actual node&lt;/li&gt;
&lt;li&gt;Move on the loop&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;
/*
* Reverse the List
* @return {SinglyLinkedList} list
*/

reverse() {

	 /**
   	 * Reverse the Linked List
    * @return {SinglyLinkedList} - The reversed list
    * @Example
    Original List: 1 -&gt; 2 -&gt; 3 -&gt; 4 -&gt; 5
    Reversed List: 1 &amp;#x3C;- 2 &amp;#x3C;- 3 &amp;#x3C;- 4 &amp;#x3C;- 5
    */

	 // If List is empty return the List
    if (this.isEmpty()) return this;

    // swap head and tail
    // And keep a reference
    // For the tail because it will be our
    // New head
    let node = this.head;
    this.tail = node;
    // We need to variable to
    // keep reference to previous and next Node
    let prev, next;

    // Loop through the list
    // We could also use the run method
    while (node) {
      // we save the next value @example 2
      next = node.next;

      // set the next node the be the previous
      // @example 2 will be the previous of 1
      node.next = prev;

      // Set previous to be the actual Node
      // @example 1
      // @example Now 2 as 1 as next 1 &amp;#x3C;- 2
      prev = node;

      // Move on to the loop
      node = next;
    }
    // When the loop is finished
    // Our prev is our reversed list
    // So we just set it to be the head
    // @example (tail)1 &amp;#x3C;- 2 &amp;#x3C;- 3 &amp;#x3C;- 4 &amp;#x3C;- 5(head)
    this.head = prev;
    return this;
  }

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;One thing that I must specify here, we are reversing the Linked List in place, we are not returning a new list, it would be too easy. :D&lt;/p&gt;
&lt;p&gt;Ok, so now it&apos;s time for recursion. The concept is always the same, but first we reverse the list using a recursive function, then finally we swap head and tail.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;
	reverseWithRecursion() {
    /**
     *
     * @param {Node} head
     * @return {Node} The reversed head of he list
     */

    function reverse(head) {
      if (!head || !head.next) {
        return head;
      }

      let tmp = reverse(head.next);
      head.next.next = head;
      head.next = null;
      return tmp;
    }
    reverse(this.head);

    // Swap head and tail
    let node = this.tail;
    this.tail = this.head;
    this.head = node;
    // Return list
    return this;
  }

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This can be a little confusing, but the idea is basically the same, looping trough the list and swap the pointer next to point to the previous.&lt;/p&gt;
&lt;p&gt;Recursion can be confusing, and to be honest I think, at least in this case, makes the code less readable compare with the classic while loop.&lt;/p&gt;
&lt;p&gt;All the code for this tutorial can be found on &lt;a href=&quot;https://github.com/antoniofull/javascript-data-structures/blob/master/src/SinglyLinkedList.js&quot;&gt;github&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Javascript is weird: Dynamic typing and coercion]]></title><description><![CDATA[When I moved the the Netherlands, in my first job I worked for a company where I was the only Front End guy in a group of Java developers…]]></description><link>https://www.antoniofullone.com/blog/javascript-dynamic-typing-coercion</link><guid isPermaLink="false">https://www.antoniofullone.com/blog/javascript-dynamic-typing-coercion</guid><pubDate>Tue, 02 Apr 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;When I moved the the Netherlands, in my first job I worked for a company where I was the only Front End guy in a group of Java developers. React wasn&apos;t in the market yet and the term SPA was mostly referring to a relaxing place to go. jQuery was still the king of the Javascript Frameworks.&lt;/p&gt;
&lt;p&gt;During our lunch discussions I was trying to make Javascript look like a cool language, until one day our lead dev told me &lt;strong&gt;&lt;em&gt;&quot;Just get over it, Javascript is weird!&quot;&lt;/em&gt;&lt;/strong&gt;. He is a very nice guy and now works as principal developer for one of the biggest company here in Europe. More important, he was right, Javascript can be weird if you don&apos;t understand some of its core principles.&lt;/p&gt;
&lt;p&gt;Some days ago, while organizing my office, I found a moleskine I had during that period where I added a lot of notes on my learning about javascript. It reminded me of this episode and I decided to convert these notes it in a series of posts using my former colleague definition: &lt;strong&gt;Javascript is weird&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;Dynamic typing and coercion&lt;/h2&gt;
&lt;p&gt;Javascript is a dynamically-typed language. This means that the JS engine will convert any variable to the proper type based on the value. If you declare&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;let ticketId = &apos;1234&apos;;
typeof ticketID; // &quot;String&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and then later on you do&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;ticketId = 5678;
typeof ticketID; // &quot;Number&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you try to do this with Python or any other statically-typed language you will get an error, but the JS engine will not. It will simply do the conversion when the code is running.&lt;/p&gt;
&lt;p&gt;Now we know that the type of &lt;code&gt;ticketID&lt;/code&gt; is a number correct? But if we do now something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;ticketID += &apos;10&apos;;
typeof ticketId; // &quot;String&quot; -&gt; WTF?
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Yep, now our ticket is again a String. I suggest to bookmark this &lt;a href=&quot;https://getify.github.io/coercions-grid/&quot;&gt;page&lt;/a&gt; and keep it as reference to understand all the WTF going on with JS and types.&lt;/p&gt;
&lt;p&gt;What is happening here is called &lt;strong&gt;coercion&lt;/strong&gt; and it refers to this conversion, done at run time, by the javascript engine. Coercion can cause a lot of unexpected bugs and it&apos;s not just about converting numbers to string. Let&apos;s look at this very simple example&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;&apos;use strict&apos;;
a = 20;
// Uncaught ReferenceError: a is not defined

// without &quot;use strict&quot;
a = 20; // 20
console.log(this.a); // 20
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The variable &lt;code&gt;a&lt;/code&gt;, without &lt;code&gt;&quot;use strict&quot;&lt;/code&gt; belongs to the global object, &lt;code&gt;window&lt;/code&gt;.
This is also one of the reason why &lt;code&gt;&quot;use strict&quot;&lt;/code&gt; is used.&lt;/p&gt;
&lt;p&gt;Same problems can arise when we compare them. I think we all know this and why it is happening:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;let numberId = 20;
let stringID = &apos;20&apos;;

console.log(numberId == stringID); // true no type compared
console.log(numberId === stringID); // false type compared
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But let&apos;s look at this one, can you guess if it&apos;s true or false?&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;console.log(1 &amp;#x3C; 2 &amp;#x3C; 3);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Of course it returns &lt;code&gt;true&lt;/code&gt;! What about this?&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;console.log(3 &amp;#x3C; 2 &amp;#x3C; 1); // true WTF?
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So what is happening here? It is obvious that 3 is greater than 2 and that 2 is greater than 1, so why it is returning true?
Let&apos;s look at it step by step&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;3 &amp;#x3C; 2 &amp;#x3C; 1;
// 3 &amp;#x3C; 2 returns a Boolean
// So the next expression is comparing the result of 3 &amp;#x3C; 2
// which is false, so is
false &amp;#x3C; 1;
// but false is not a number
// so the JS engine will convert it to a Number in order to compare it
Number(false) &amp;#x3C; 1;
// converting false to a number returns 0
// thus 0 is less than 1 and so ... true
0 &amp;#x3C; 1; // true
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The same was for the previous expression, 1 is less than 2 so now we compare true to 3 and &lt;code&gt;Number(true)&lt;/code&gt; returns 1 so 1 is less than 3, the expression returns true.
&lt;code&gt;Number(false)&lt;/code&gt; will return 0, so that means that if we do something like :&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;ticketID = 0;
// our variable ticketID is equal to 0 and so is false
if (ticketID) {
  // NOthing happens, ticketID is false
  // The if statement converts ticketID to boolean
  // Boolean(0) -&gt; false
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In javascript, 0 is coerced to false when converted to a Boolean, same goes for an empty string or undefined or null&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;let num = 0;
let str = &apos;&apos;;
let a;
// These are all false
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Also &lt;code&gt;NaN&lt;/code&gt; returns false. NaN stands for &quot;Not A Number&quot; but its type is number, confusing uh?&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;typeof NaN; // Number!!
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When you do &lt;code&gt;typeof null&lt;/code&gt; or &lt;code&gt;typeof []&lt;/code&gt; it will return object.&lt;/p&gt;
&lt;h3&gt;Explicit Vs Implicit Coercion&lt;/h3&gt;
&lt;p&gt;Coercion can be explicit or implicit. It is explicit when we are defining it&apos;s type, like &lt;code&gt;Number(&apos;20&apos;)&lt;/code&gt; and it is implicit when we let the JS engine do the conversion like &lt;code&gt;let counter = 20&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Finally the last &quot;WTF&quot; :)&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;let myVar;
Number(myVar); // NaN

let myNewVar = null; // never do that
Number(myNewVar); // 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So yes, some parts of javascript are weird, others are &lt;a href=&quot;http://shop.oreilly.com/product/9780596517748.do&quot;&gt;good&lt;/a&gt;.
I will try to write other posts taken from these notes, so hopefully with this post I can also announce that I am &lt;strong&gt;&lt;em&gt;back to blogging&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Final note:
&lt;a href=&quot;https://github.com/Microsoft/TypeScript&quot;&gt;Typescript&lt;/a&gt; and &lt;a href=&quot;https://flow.org/&quot;&gt;Flow&lt;/a&gt; are the 2 most well known solutions for using static types in JS, Typescript is a superset of javascript(Js with super powers), flow is a static checker.&lt;/p&gt;
&lt;p&gt;Image credits: &lt;a href=&quot;https://www.reddit.com/r/ProgrammerHumor/comments/6vsv4g/javascript_meme/&amp;#x27;&quot;&gt;Programming Humor&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Kitesurfing Lessons]]></title><description><![CDATA[Last week I started my kitesurf lessons here in Canary Islands. I have a very funny and nice instructor. He is Austrian and soo german in…]]></description><link>https://www.antoniofullone.com/blog/kitesurfing-canary-islands</link><guid isPermaLink="false">https://www.antoniofullone.com/blog/kitesurfing-canary-islands</guid><pubDate>Sun, 18 Feb 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Last week I started my &lt;strong&gt;kitesurf lessons&lt;/strong&gt; here in &lt;strong&gt;Canary Islands&lt;/strong&gt;. I have a very funny and nice instructor. He is Austrian and soo german in his teaching. Anyway it is very fun, for now I had few lessons and always on the land, learning how to control the kite and how to standup and sit down with it. I am feeling very excited about starting this new sport.&lt;/p&gt;
&lt;p&gt;I was struggling on which type of water sport I could do. I would have loved to do diving, but unfortunately because of my ear problems is something that it can be very risky for my health. Diving has always been my dream so when I found out that I could not do it, honestly it broke my heart.&lt;/p&gt;
&lt;p&gt;Surf is another option I evaluated here in Lanzarote, unfortunately the best place to do surf is a little bit far away from where I live and since I don&apos;t have a car yet, it is a problem.&lt;/p&gt;
&lt;p&gt;So I ended up with &lt;strong&gt;kitesurfing&lt;/strong&gt;. The school is very close to my house and the sport is still fun and nice. I can ride on the ocean and I look forward to the moment I can finally enter the water and do my first long ride :smile:&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sort an array of objects by date using moment]]></title><description><![CDATA[Sorting and ordering an array is quite easy, just use array.sort and pass the function which will sort it. Something like this: Last week I…]]></description><link>https://www.antoniofullone.com/blog/momentjs-order-date</link><guid isPermaLink="false">https://www.antoniofullone.com/blog/momentjs-order-date</guid><pubDate>Sun, 07 Jan 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Sorting and ordering an array is quite easy, just use &lt;code&gt;array.sort&lt;/code&gt; and pass the function which will sort it. Something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;const arr = [0, 10, 2, 3];
const newarr = arr.sort((a, b) =&gt; {
  return a - b;
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Last week I needed to order an array of objects by their date. The array uses &lt;a href=&quot;https://momentjs.com&quot;&gt;momentjs&lt;/a&gt; to render the dates. Looking at the moment documentation, very well written, I found easily the solution:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;const arr = [
  { _id: 1, createdAt: moment(&apos;Sat Jan 07 2018 11:50:21 GMT+0000 (WET)&apos;) },
  { d_id: 2, createdAt: moment(&apos;Sat Jan 06 2018 11:50:21 GMT+0000 (WET)&apos;) }
];

const newarr = arr.sort((a, b) =&gt; {
  return moment(a.createdAt).diff(b.createdAt);
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will sort the array by date with &lt;strong&gt;moment&lt;/strong&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[22 Years]]></title><description><![CDATA[Today it’s my birthday. 22 Years ago on this day I turned 16th. 22 Years ago on this day my father died. Every year on this day I wake up…]]></description><link>https://www.antoniofullone.com/blog/22-years</link><guid isPermaLink="false">https://www.antoniofullone.com/blog/22-years</guid><pubDate>Thu, 24 Sep 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Today it’s my birthday. 22 Years ago on this day I turned 16th. 22 Years ago on this day my father died. Every year on this day I wake up living the same scene, I see my mum crying, my sisters in shock, my little sister taken away by my aunt.It could have happened a day later or before, but no, it happened just on my birthday.&lt;/p&gt;
&lt;p&gt;A lot of people told me that was a “sign of the destiny” but I don’t believe in that, I don’t believe in those religious things, I just know that he’s gone, just on the most important day of my life.&lt;/p&gt;
&lt;p&gt;He was for me like a hero, my inspiration on doing everything. The day before he promised me to let me take the driver license for the motorbike, I was dreaming to get one. He knew he was dying but he smiled at me and said yes, because he would never disappoint his family.
He taught me how important is to love your family.&lt;/p&gt;
&lt;p&gt;He looked always serious from outside but was a funny man in private, with his sons. He was strong, very respected among all our relatives and friends, everyone who had a problem or just need advices would look for him, he had always the right answer and suggestion for everyone.&lt;/p&gt;
&lt;p&gt;I am not like him, but I wish I was. I don’t even look like my age, when people ask me how old I am they look at me surprised &quot;Really?&quot; ... I don’t even get close to be like him. The day after his death I promised myself I would do everything to make him proud of me.&lt;/p&gt;
&lt;p&gt;I never celebrated my birthday again, Jesus, how can I? For years I wondered what can I do to survive this day, then year by year I slowly started to realise:
I cannot change what happened, I have all the rights to do not celebrate my birthday but I cannot hide myself behind tears or rage, the only thing I can do is to do my best to keep my promise, make him proud of his son.&lt;/p&gt;
&lt;p&gt;I listen to the same song all the day, and then the day ends, I go to sleep and another year is gone.&lt;/p&gt;
&lt;p&gt;It&apos;s been 22 years, but I still miss You.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Off Canvas with only Css]]></title><description><![CDATA[Yesterday evening I was bored at home (as usual) and the weather was cold (as usual) so I decided to spend some time fixing some bug on this…]]></description><link>https://www.antoniofullone.com/blog/off-canvas-css</link><guid isPermaLink="false">https://www.antoniofullone.com/blog/off-canvas-css</guid><pubDate>Fri, 03 Apr 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Yesterday evening I was bored at home (as usual) and the weather was cold (as usual) so I decided to spend some time fixing some bug on this site.&lt;/p&gt;
&lt;p&gt;I linked the &quot;contact&quot; link in the navigation to the contact section in the footer. My friend &lt;a href=&quot;https://twitter.com/twittgrinder&quot;&gt;Marco&lt;/a&gt; suggested me that this way was not clear on how to find to contact so I looked for a solution, which I founded in the :target &lt;a href=&quot;https://www.w3.org/wiki/CSS/Selectors/pseudo-classes/:target&quot;&gt;pseudo selector&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;How :target work is pretty simple, it just matches the selector id with the hash in the url. So if you have a url like this mysite.com/#contact you can style your element with #contact:target. And so I did for the email link in the footer and highlight the email link in bold-red when matching the target.&lt;/p&gt;
&lt;p&gt;After that I started to experiment a little bit with this selector, and i came up with this (kinda of silly) off canvas.
Basically with no javascript and no &lt;a href=&quot;https://css-tricks.com/the-checkbox-hack/&quot;&gt;checkbox hack&lt;/a&gt; it is possible to create a complete menu. Another trick I used is on the close button, where I just change the #hash and so removing the style to the sidebar. You can check the example &lt;a href=&quot;/off-canvas/&quot;&gt;here&lt;/a&gt; and on &lt;a href=&quot;https://codepen.io/lastwebdesigner/pen/JoVVOp&quot;&gt;codepen&lt;/a&gt;, and the code &lt;a href=&quot;https://bitbucket.org/afullone/off-canvas-with-css&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Of course keep in mind that is something that would never end up in production but it was fun to play with it. Highliting the section I think is ok to use it, as it is just an enhancement. :D&lt;/p&gt;
&lt;p&gt;Go to example : &lt;a href=&quot;/off-canvas/&quot;&gt;Off Canvas with only Css using the :target pseudo selector&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Bye Bye Wordpress, welcome Jekyll!]]></title><description><![CDATA[I use to blog a couples of times for year, maybe three. Wordpress is really too much for me, I am tired of dealing with updates, database…]]></description><link>https://www.antoniofullone.com/blog/jekyll-wordpress</link><guid isPermaLink="false">https://www.antoniofullone.com/blog/jekyll-wordpress</guid><pubDate>Mon, 27 Oct 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I use to blog a couples of times for year, maybe three. Wordpress is really too much for me, I am tired of dealing with updates, database, plugins, spam. I did a first small move the last time that I redesigned my blog, making the about and home page static, and moving only to (real) blog part to Wordpress, but it turnout that was even more hard to maintain.&lt;/p&gt;
&lt;p&gt;Also the template system in Wordpress is complex while I, as you can see, I like to keep this site much simple as possible.&lt;/p&gt;
&lt;p&gt;The answer to all my questions is Jekyll. I was intrigued to use it, but a little bit “scared”, I found out instead that is really easy to set up and use. I installed the Mac version, opened my Textmate and started moving the code from Wordpress to static pages in less than a weekend.&lt;/p&gt;
&lt;p&gt;Jekyll has his own template system, and once you do the build, the only thing is to use the same name pattern for the posts.&lt;/p&gt;
&lt;p&gt;Another reason why I moved to Jekyll is the fact that I love writing with IAWriter, which has a very good support for Markdown, and Jekyll uses Markdown for its posts, so it’s a perfect combination.&lt;/p&gt;
&lt;p&gt;The last thing to do was to find a good way to avoid to deploy manually every time, so I found &lt;a href=&quot;https://github.com/dmathieu/glynn&quot;&gt;Glynn&lt;/a&gt; which does the job for you, deploying also on the FTP.&lt;/p&gt;
&lt;p&gt;Next step is to move also my italian blog (which basically will just be a copy of this one, but probably different contents) where I use to blog more often, like 6/7 times a year.&lt;/p&gt;
&lt;p&gt;I am very happy now with the results, here some simple advantages I found on Jekyll:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Template : as I said above, easy, simple faster.&lt;/li&gt;
&lt;li&gt;Static pages mean also speed, the page now load much faster.&lt;/li&gt;
&lt;li&gt;Easy writing with Markdown.&lt;/li&gt;
&lt;li&gt;Ridiculously easy to update and maintain. You just need a grunt file.&lt;/li&gt;
&lt;li&gt;More freedom on styling and editing the posts, I can get rid of the rigid template system and build custom post each time I want.&lt;/li&gt;
&lt;li&gt;Easy to update. It’s just html right? :D&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item></channel></rss>