<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>Tony Xu Blog - English</title><description>English-language posts from Tony Xu Blog.</description><link>https://tonyxu.io/</link><language>en</language><atom:link href="https://tonyxu.io/rss/en.xml" rel="self" type="application/rss+xml"/><item><title>My second brain setup</title><link>https://tonyxu.io/blog/my-second-brain-setup/</link><guid isPermaLink="true">https://tonyxu.io/blog/my-second-brain-setup/</guid><description>How I set up a private Markdown-first second brain with semantic search, AI agents, raw capture, and quiet automation.</description><pubDate>Fri, 08 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;How I set up a private Markdown-first second brain with semantic search, AI agents, raw capture, and quiet automation.&lt;/p&gt;
</content:encoded><dc:language>en</dc:language><category>AI</category><category>Productivity</category></item><item><title>The Next AI Race May Be Won at the Application Layer</title><link>https://tonyxu.io/blog/ai-competition-application-layer/</link><guid isPermaLink="true">https://tonyxu.io/blog/ai-competition-application-layer/</guid><description>Why the next phase of AI competition may depend less on the best foundation model and more on how quickly teams turn AI into products, companies, and workflows.</description><pubDate>Fri, 01 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I have been thinking about this for a while: AI competition is not only about who has the best foundation model.&lt;/p&gt;
&lt;p&gt;Models matter. Chips matter. Infrastructure matters. But the next stage may be more about who can turn AI into real products, real companies, and real workflows faster.&lt;/p&gt;
&lt;p&gt;That is why I am increasingly optimistic about China’s AI application layer.&lt;/p&gt;
&lt;p&gt;This is not a prediction that China will “beat” the US. The US will continue to lead in many frontier areas, including research, chips, cloud platforms, the developer ecosystem, and globally distributed AI products. The more interesting question is what kind of AI-native ecosystem China will build for its own market—and what that ecosystem might teach the rest of the world.&lt;/p&gt;
&lt;h2&gt;The model layer is only the beginning&lt;/h2&gt;
&lt;p&gt;The foundation-model race gets most of the attention because it is easy to measure: benchmark scores, context windows, training runs, and model launches. Those things are important, but they are not the same as building useful products.&lt;/p&gt;
&lt;p&gt;As models become cheaper, more capable, and easier to integrate, the application layer becomes more important. The advantage may shift toward the teams that can identify valuable problems, design better workflows, and iterate quickly enough to keep up with the technology.&lt;/p&gt;
&lt;p&gt;The companies that emerge from this wave will not simply add an AI feature to an existing product. Many will be designed around AI from day one:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;smaller teams with more leverage;&lt;/li&gt;
&lt;li&gt;faster product cycles;&lt;/li&gt;
&lt;li&gt;more automation built into everyday operations;&lt;/li&gt;
&lt;li&gt;workflows designed around what AI can do, rather than around older software boundaries.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The model is a building block. The product is where users experience the value.&lt;/p&gt;
&lt;h2&gt;Why China’s application layer is interesting&lt;/h2&gt;
&lt;p&gt;China has a large pool of technology talent, a huge consumer market, a strong hardware supply chain, and a culture that is generally open to new technology. It also has a history of fast product iteration and intense competition.&lt;/p&gt;
&lt;p&gt;We saw this pattern with mobile internet, social networks, mobile payments, and crypto/web3. China did not simply copy the US market. It developed its own product patterns, user behaviors, and business ecosystems in response to local conditions.&lt;/p&gt;
&lt;p&gt;AI may follow a similar path.&lt;/p&gt;
&lt;p&gt;The key opportunity is not just access to a powerful model. It is the combination of capable models, local distribution, user behavior, engineering execution, and a willingness to redesign how work gets done. Those factors can create products that look different from their American counterparts even when they are built on similar underlying technology.&lt;/p&gt;
&lt;h2&gt;A lively model ecosystem&lt;/h2&gt;
&lt;p&gt;Chinese foundation-model companies are already serious participants in the global conversation. DeepSeek, &lt;a href=&quot;https://z.ai/&quot;&gt;Z.ai&lt;/a&gt;, MiniMax, Qwen, Kimi, and others are building a diverse ecosystem. They may not all win, but the ecosystem is clearly alive.&lt;/p&gt;
&lt;p&gt;That diversity matters. Competition at the model layer can push costs down and capabilities up. More importantly, it gives application builders more options: different model personalities, deployment choices, pricing models, and trade-offs between speed, quality, and control.&lt;/p&gt;
&lt;p&gt;When the cost of intelligence falls, more ideas become economically viable. A small team can test a product that would previously have required a much larger organization. An existing company can automate a process that used to be too expensive to improve. Entirely new workflows become possible.&lt;/p&gt;
&lt;h2&gt;From AI-enabled to AI-native&lt;/h2&gt;
&lt;p&gt;There is a meaningful difference between an existing company that uses AI and a company designed around AI from the beginning.&lt;/p&gt;
&lt;p&gt;An AI-enabled company may add a chatbot, generate marketing copy, or automate a few internal tasks. An AI-native company can rethink its operating model: how it serves customers, how it makes decisions, how its employees collaborate, and which parts of the business need to exist at all.&lt;/p&gt;
&lt;p&gt;That shift could produce companies with very different shapes from the software companies we are used to. They may have fewer employees, rely on more automated processes, and move from idea to product much faster. Their advantage may come less from owning a large organization and more from designing a system in which people and models work together effectively.&lt;/p&gt;
&lt;p&gt;This is where application-layer competition becomes especially interesting. The winners may not be the companies with the biggest training budget. They may be the ones that understand a specific market deeply and move quickly enough to turn that understanding into a useful product.&lt;/p&gt;
&lt;h2&gt;A more useful question&lt;/h2&gt;
&lt;p&gt;The US–China framing is tempting, but “who will win AI?” is probably too simple a question.&lt;/p&gt;
&lt;p&gt;The US and China have different strengths, markets, constraints, and product cultures. The US may continue to lead in many frontier capabilities and global platforms. China may build a very large and distinctive AI-native ecosystem for its own market. Both can be true at the same time.&lt;/p&gt;
&lt;p&gt;The more useful question is: what kinds of companies and workflows will each ecosystem create when AI becomes cheap, capable, and ubiquitous?&lt;/p&gt;
&lt;p&gt;In the last wave, mobile internet changed how people live. This wave may change how companies are built.&lt;/p&gt;
&lt;p&gt;That is why I am watching the application layer so closely. The next important AI story may not be another model release. It may be the company that uses existing models to build an entirely new way of working.&lt;/p&gt;
&lt;div&gt;
  This essay expands on a &lt;a href=&quot;https://www.linkedin.com/feed/update/urn:li:activity:7456071270372200448/&quot;&gt;LinkedIn post&lt;/a&gt; I shared earlier.
&lt;/div&gt;</content:encoded><dc:language>en</dc:language><category>AI</category><category>Strategy</category><category>Product</category></item><item><title>Top Engineering Blogs from Tech Companies to Follow in 2023</title><link>https://tonyxu.io/blog/top-engineering-blogs-from-tech-companies-to-follow-in-2023/</link><guid isPermaLink="true">https://tonyxu.io/blog/top-engineering-blogs-from-tech-companies-to-follow-in-2023/</guid><description>Company engineering blogs I followed in 2023 to learn about reliable systems, infrastructure, and engineering practice.</description><pubDate>Thu, 13 Apr 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Company engineering blogs I followed in 2023 to learn about reliable systems, infrastructure, and engineering practice.&lt;/p&gt;
</content:encoded><dc:language>en</dc:language><category>Engineering</category><category>Reading</category></item><item><title>My Productivity Tools and Development Setup in 2019</title><link>https://tonyxu.io/blog/2019-productivity-tools/</link><guid isPermaLink="true">https://tonyxu.io/blog/2019-productivity-tools/</guid><description>The hardware, software, and development setup I used to stay productive in 2019.</description><pubDate>Fri, 01 Feb 2019 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;This article describes the setup I used in 2019. Several products, plans, and links have changed or been discontinued.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Hardware&lt;/h2&gt;
&lt;h3&gt;Laptop&lt;/h3&gt;
&lt;p&gt;👉 &lt;a href=&quot;https://support.apple.com/kb/SP755?locale=en_US&quot;&gt;Apple MacBook Pro (13-inch, 2017, Four Thunderbolt 3 Ports)&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;13-inch&lt;/li&gt;
&lt;li&gt;2017 Year&lt;/li&gt;
&lt;li&gt;3.5 GHz Intel Core i7 Processor&lt;/li&gt;
&lt;li&gt;16 GB Memory&lt;/li&gt;
&lt;li&gt;256 GB Storage&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;My MacBook Pro (company provided) is my most important productivity tool. I use it to code, write blogs, and everything else.&lt;/p&gt;
&lt;h3&gt;Mobile Phone&lt;/h3&gt;
&lt;p&gt;👉 &lt;a href=&quot;https://support.apple.com/kb/SP770?locale=en_US&quot;&gt;Apple iPhone X&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I&apos;m using iPhone X as my mobile phone. I have been an iPhone person ever since 2013 from an iPhone 4. Before iPhone, I have been playing with Android phones (Nexus S) for a while. The iOS ecosystem, better notification system and app quality are the key reasons I stick with iOS devices.&lt;/p&gt;
&lt;h3&gt;Desktop&lt;/h3&gt;
&lt;p&gt;I don&apos;t actually have a desktop machine. Since my employer has $150 Azure credits for employees so I just created a &lt;a href=&quot;https://azure.microsoft.com/en-us/pricing/details/virtual-machines/windows/&quot;&gt;Windows VM in Azure&lt;/a&gt; to use as a Windows desktop machine. I used the VM to install/test any software that is only available for Windows, for example, &lt;a href=&quot;https://powerbi.microsoft.com/en-us/desktop/&quot;&gt;Power BI Desktop&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Work Station (where I work)&lt;/h3&gt;
&lt;p&gt;👉 ThinkVision P27h (dual monitors)&lt;/p&gt;
&lt;p&gt;Provided for me to use at work. I connect my laptop to two external monitors and I usually have my laptop open slack window, one external monitor open Chrome browser, and one monitor open Outlook/VS Code. It also supports USB Type-C so you can get display output and charging with just one cable.&lt;/p&gt;
&lt;p&gt;👉 &lt;a href=&quot;http://store.hermanmiller.com/office/desks-%7C-sit-to-stand-%7C-tables/renew-sit-to-stand-desk/7090.html?lang=en_US&quot;&gt;Herman Miller - Renew Sit-to-Stand Desk Rectangular&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Provided for me to use at work. Although it&apos;s cool and encourages you to stand to work to keep healthy, I felt more comfortable sitting behind it.&lt;/p&gt;
&lt;p&gt;👉 &lt;a href=&quot;https://support.apple.com/kb/SP763?locale=en_US&quot;&gt;Apple Magic Keyboard with Numeric Keypad&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The external keyboard allows me to put my laptop farther from me and more close to other monitors so the three screens can be almost in the same surface.&lt;/p&gt;
&lt;p&gt;👉 &lt;a href=&quot;https://support.apple.com/kb/SP729?locale=en_US&quot;&gt;Apple Magic Trackpad 2&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I&apos;m really a fan of trackpad. I can never go back to the old time when I was using a mouse. When I&apos;m using an external keyboard, I have to have an external trackpad as well since I can&apos;t get to the trackpad of the MacBook.&lt;/p&gt;
&lt;h3&gt;Accessories&lt;/h3&gt;
&lt;p&gt;👉 &lt;a href=&quot;https://support.apple.com/kb/SP750?locale=en_US&quot;&gt;Apple AirPods&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;AirPods are my favorite accessory because they are convenient, and I often forget I am wearing them. Unlike in-ear earphones that can make it hard to hear other people, AirPods let you notice when someone is trying to talk to you without needing to tap you for attention.&lt;/p&gt;
&lt;p&gt;👉 &lt;a href=&quot;https://support.apple.com/kb/sp735?locale=en_US&quot;&gt;Apple Watch (1st generation)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I have been using Apple Watch since 2014 when its first generation was released. Apple Watch is great for people like me who don&apos;t bother taking out iPhone from pocket to just read notifications. Apple Watch does this one job for me and does it well.&lt;/p&gt;
&lt;h2&gt;Software&lt;/h2&gt;
&lt;h3&gt;macOS Apps&lt;/h3&gt;
&lt;p&gt;👇&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.google.com/chrome/&quot;&gt;Chrome&lt;/a&gt;: One of the most popular browsers in the world. I use it for web development because it offers a great debugging experience.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.slack.com/&quot;&gt;Slack&lt;/a&gt;: The most popular team collaboration app, great for developers. It integrates with almost all your development tools and services to streamline your development workflow and team collaboration experience.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://code.visualstudio.com/&quot;&gt;VS Code&lt;/a&gt;: I used to be a Sublime Text fan, but switched to VS Code in 2016 because of its active development and extension community. Refer to &lt;a href=&quot;https://tonyxu.io/blog/2019-productivity-tools/#vs-code-extensions&quot;&gt;VS Code Extensions&lt;/a&gt; for the extensions I use.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.sketchapp.com/&quot;&gt;Sketch&lt;/a&gt;: Most popular web/app design software (macOS only). Very easy to create web/app design without professional design knowledge. I used it to design web/app prototypes and read design spec from designers.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://desktop.github.com/&quot;&gt;GitHub Desktop&lt;/a&gt;: An official desktop client for GitHub. I use it as an alternative for Git commands when I want to get visualized diffs.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://paw.cloud/&quot;&gt;Paw&lt;/a&gt;: An advanced REST API desktop client for macOS. I like it much more than Postman, which is more of a web app. Paw has a native macOS interface and extensions for advanced needs. I use it to troubleshoot REST API requests.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://itunes.apple.com/us/app/microsoft-remote-desktop-10/id1295203466&quot;&gt;Microsoft Remote Desktop&lt;/a&gt;: A Windows remote desktop client. I use it to connect to Azure Windows VM.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.alfredapp.com/&quot;&gt;Alfred 3&lt;/a&gt;: A shortcut tool. There are many great plugins that allow you to trigger automation from shortcut. I use it for searching, clipboard history, snippet, and uploading images from pasteboard.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bear.app/&quot;&gt;Bear&lt;/a&gt;: A markdown note app. Element UI and smooth typing experience.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.bluejeans.com/&quot;&gt;BlueJeans&lt;/a&gt;/&lt;a href=&quot;https://zoom.us/&quot;&gt;Zoom&lt;/a&gt;/&lt;a href=&quot;https://www.webex.com/&quot;&gt;WebEx&lt;/a&gt;: Online meeting, to have video meeting with your team members without having to meet in person.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.charlesproxy.com/&quot;&gt;Charles&lt;/a&gt;: A web proxy that allows you to debug network traffic. I use it to inspect network requests made outside the Chrome browser.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://filezilla-project.org/&quot;&gt;FileZilla&lt;/a&gt;: An FTP tool that helps you upload and download files to and from a remote host.&lt;/li&gt;
&lt;li&gt;GIF Brewery 3: A GIF maker app for macOS. I used it to record screen as a GIF so that when I shared it with others it was easier to view than a video clip. Its former Gfycat page is no longer available.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://magnet.crowdcafe.com/&quot;&gt;Magnet&lt;/a&gt;: A macOS window manager. I usually have multiple apps opened in multiple monitors, it&apos;s really helpful to use shortcut to move and resize apps between monitors.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.office.com/&quot;&gt;Microsoft Office Word/Excel/Outlook/PowerPoint/Teams&lt;/a&gt;: Classic office productivity suite provided by Microsoft.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://monosnap.com/&quot;&gt;Monosnap&lt;/a&gt;: A free advanced screenshot tool. You can make annotations with the screenshot and it has integration with cloud storage so you can get a sharable link immediately.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://reederapp.com/&quot;&gt;Reeder&lt;/a&gt;: An RSS reader. You can also login with third-party RSS manager account. I subscribed engineering blogs from major tech companies so that I can get latest technology trend update from major tech companies.&lt;/li&gt;
&lt;li&gt;Sequel Pro: A database management tool that helped manage MySQL databases with a graphical interface.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/shadowsocks/ShadowsocksX-NG&quot;&gt;ShadowsocksX-NG&lt;/a&gt;: A Shadowsocks client. It helps me to get access to some apps that were blocked (e.g. Google in China).&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://typora.io/&quot;&gt;Typora&lt;/a&gt;: A markdown editor that render as you type. You don&apos;t need to look at raw text on the left and rendered on the right anymore.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Mac Terminal&lt;/h3&gt;
&lt;p&gt;Terminal is probably one of the most-used apps for software engineers. Check out &lt;a href=&quot;https://tonyxu.io/blog/ultimate-way-to-beautify-mac-terminal-and-recommendations-for-plugins/&quot;&gt;Ultimate way to beautify Mac terminal (oh-my-zsh) and plugin recommendations&lt;/a&gt; for a complete guide to improving your terminal workflow.&lt;/p&gt;
&lt;h3&gt;VS Code Extensions&lt;/h3&gt;
&lt;p&gt;One reason I choose VS Code as my preferred code editor is its rich extensions marketplace. Here is a list of VS Code extensions I use:&lt;/p&gt;
&lt;p&gt;👇&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=akamud.vscode-theme-onedark&quot;&gt;Atom One Dark Theme&lt;/a&gt;: A theme based on Atom&apos;s One Dark theme.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=HookyQR.beautify&quot;&gt;Beautify&lt;/a&gt;: Beautify Javascript, JSON, CSS, Sass, and HTML in Visual Studio Code.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker&quot;&gt;Code Spell Checker&lt;/a&gt;: A basic spell checker that helps catch common spelling errors.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=bmaupin.copy-without-formatting&quot;&gt;Copy without formatting&lt;/a&gt;: Prevent background/font format being pasted&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint&quot;&gt;ESLint&lt;/a&gt;: An essential tool that helps me write clean JavaScript code.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode&quot;&gt;Prettier - Code formatter&lt;/a&gt;: Format your Javascript/TypeScript/CSS code&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=mechatroner.rainbow-csv&quot;&gt;Rainbow CSV&lt;/a&gt;: Highlight CSV columns&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=wayou.vscode-todo-highlight&quot;&gt;TODO Highlight&lt;/a&gt;: Highlight &lt;code&gt;TODO&lt;/code&gt;, &lt;code&gt;FIXME&lt;/code&gt; in code&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;iOS Apps&lt;/h3&gt;
&lt;p&gt;👇&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://itunes.apple.com/us/app/slack/id618783545&quot;&gt;Slack&lt;/a&gt;: Same as on macOS, used just for quickly read and respond to messages.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://itunes.apple.com/us/app/pphub-for-github/id1314212521&quot;&gt;PPHub&lt;/a&gt;: A third-party GitHub mobile client. You can view trending projects/developers and updates from your following account.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://itunes.apple.com/us/app/eudic-%E6%AC%A7%E8%B7%AF%E8%AF%8D%E5%85%B8/id434350458&quot;&gt;Eudic&lt;/a&gt;: A simple dictionary that has little to no ads.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://itunes.apple.com/us/app/google/id284815942&quot;&gt;Google&lt;/a&gt;: Google anything you want to know.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://itunes.apple.com/us/app/scanbot-scanner-app-scan-pdf/id834854351&quot;&gt;Scanbot&lt;/a&gt;: A free scanner app that has great user experience&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Chrome Extensions&lt;/h3&gt;
&lt;p&gt;👇&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.grammarly.com/&quot;&gt;Grammarly&lt;/a&gt;: Fixes grammar issues for me. Really helpful when writing emails or documentations.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://chrome.google.com/webstore/detail/save-page-we/dhhpefjklgkmgeafimnjhojgjamoafof?hl=en-US&quot;&gt;Save Page WE&lt;/a&gt;: When I use &lt;em&gt;Save Page As&lt;/em&gt; feature provided by Chrome, it actually exported html with lots of assets files. This extension actually exported as a single HTML file, which makes it easier to share.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://chrome.google.com/webstore/detail/awesome-screenshot-screen/nlipoenfbbikpbjkfpfillcgkoblgpmj?hl=en&quot;&gt;Awesome Screenshot&lt;/a&gt;: Take screenshot from web pages&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://chrome.google.com/webstore/detail/jsonview/chklaanhfefbnpoihckbnefhakgolnmc?utm_source=chrome-ntp-icon&quot;&gt;JSONView&lt;/a&gt;: Format JSON response in a more readable format&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://chrome.google.com/webstore/detail/builtwith-technology-prof/dapjbgnjinbpoindlpdmhochffioedbn?utm_source=chrome-ntp-icon&quot;&gt;BuiltWith&lt;/a&gt;: Tells you what technology the current website uses&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Cloud-based Service&lt;/h2&gt;
&lt;p&gt;👇&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://ifttt.com/&quot;&gt;IFTTT&lt;/a&gt; (If This Then That): Set up automation between apps and services. I use it to automate the smart lights at home when I arrive or leave.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/&quot;&gt;GitHub&lt;/a&gt;: GitHub is a community all developers love. I use GitHub to manage my code, knowledge, projects, and static websites. I also discover and contribute to interesting open-source projects. Check out &lt;a href=&quot;https://tonyxu.io/blog/my-second-brain-setup/&quot;&gt;My Second Brain Setup&lt;/a&gt; for how I use it to manage my knowledge and projects.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://firebase.google.com/&quot;&gt;Firebase&lt;/a&gt;: Firebase gives you lots of out-of-the-box cloud solution for free, for example, &lt;a href=&quot;https://firebase.google.com/products/database&quot;&gt;real time database&lt;/a&gt;, &lt;a href=&quot;https://firebase.google.com/products/storage/&quot;&gt;cloud storage&lt;/a&gt;, &lt;a href=&quot;https://firebase.google.com/products/functions/&quot;&gt;cloud functions&lt;/a&gt;, and &lt;a href=&quot;https://firebase.google.com/products/hosting/&quot;&gt;hosting&lt;/a&gt;. It makes it almost 0 cost to spin up a demo app.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://heroku.com/&quot;&gt;Heroku&lt;/a&gt;: Heroku is a cloud platform to deploy apps. It is free for experimental use. I use it to deploy Node.js app where free static hosting services like &lt;a href=&quot;http://pages.github.com/&quot;&gt;Github Pages&lt;/a&gt; or &lt;a href=&quot;https://firebase.google.com/products/hosting/&quot;&gt;Firebase Hosting&lt;/a&gt; can&apos;t support.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cloud.google.com/&quot;&gt;Google Cloud&lt;/a&gt;, &lt;a href=&quot;https://aws.amazon.com/&quot;&gt;Amazon Web Services (AWS)&lt;/a&gt;, &lt;a href=&quot;https://azure.microsoft.com/en-us/&quot;&gt;Microsoft Azure&lt;/a&gt;: These are major cloud computing service provider, some services are even free for developers to get started with. For example, &lt;a href=&quot;https://cloud.google.com/free/docs/gcp-free-tier#always-free&quot;&gt;Google Cloud - Always Free&lt;/a&gt;, &lt;a href=&quot;https://aws.amazon.com/free/free-tier/?awsf.Free%20Tier%20Types=categories%23alwaysfree&amp;amp;awsm.page=1&quot;&gt;AWS - Always Free&lt;/a&gt;, &lt;a href=&quot;https://azure.microsoft.com/en-us/free/free-account-faq/&quot;&gt;Azure - Free Account&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://jsfiddle.net/&quot;&gt;JSFiddle&lt;/a&gt;: An online HTML/JS/CSS editor, where you can test and run your code. I use it to test and share JS/HTML/CSS code snippet.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://travis-ci.org/&quot;&gt;Travis CI&lt;/a&gt;, &lt;a href=&quot;https://circleci.com/&quot;&gt;Circle CI&lt;/a&gt;: Continuous integration services used to build and test software projects hosted at GitHub. I use them to build and deploy static websites hosted on GitHub.&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><dc:language>en</dc:language><category>Productivity</category><category>Tools</category></item><item><title>Embed Google Analytics Dashboard on Website with Server Side Authorization</title><link>https://tonyxu.io/blog/embed-google-analytics-dashboard-on-website-with-server-side-authorization/</link><guid isPermaLink="true">https://tonyxu.io/blog/embed-google-analytics-dashboard-on-website-with-server-side-authorization/</guid><description>A 2018 implementation note for the discontinued Universal Analytics Embed API; it does not work with GA4.</description><pubDate>Mon, 15 Oct 2018 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;This integration no longer works.&lt;/strong&gt; It uses the Universal Analytics Embed API and &lt;code&gt;ga:&lt;/code&gt; views, not Google Analytics 4. Universal Analytics was discontinued, so this example is not GA4-compatible and should not be used for a new integration.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If you use Google Analytics to analyze site traffic, you may want to embed its dashboards in your website. Google does not provide a simple iframe solution, but it does offer a &lt;a href=&quot;https://developers.google.com/analytics/devguides/reporting/embed/v1/&quot;&gt;Google Analytics Embed API&lt;/a&gt; that requires a little more technical knowledge. This article records the implementation steps.&lt;/p&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Embedded Google Analytics dashboard preview&quot; src=&quot;https://tonyxu.io/_astro/embed-google-analytics-1.fcsDklRz.webp&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;1. Create project in &lt;a href=&quot;https://console.developers.google.com/&quot;&gt;Google Developers Console&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;(Ignore this step if you already have Google Developers Project)&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;2. Create service account and download &lt;code&gt;.json&lt;/code&gt; key file&lt;/h2&gt;
&lt;p&gt;&lt;img alt=&quot;Google Developers Console service account creation screen&quot; src=&quot;https://tonyxu.io/_astro/embed-google-analytics-2.C9EFKbDT.webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Service account JSON key download confirmation&quot; src=&quot;https://tonyxu.io/_astro/embed-google-analytics-3.CeOYnVGH.webp&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;3. Enable Google Analytics API&lt;/h2&gt;
&lt;p&gt;&lt;img alt=&quot;Google Developers Console with the Analytics API enabled&quot; src=&quot;https://tonyxu.io/_astro/embed-google-analytics-4.CygLA_8B.webp&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;4. Grant service account to access Analytics account&lt;/h2&gt;
&lt;p&gt;Obtain service account email address&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Service account email address in Google Developers Console&quot; src=&quot;https://tonyxu.io/_astro/embed-google-analytics-5.BaPjSKRi.webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Add as read only user in Analytics account user management&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Google Analytics user management with the service account added as read-only&quot; src=&quot;https://tonyxu.io/_astro/embed-google-analytics-6.Ds59RNWF.webp&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;5. Generate access token in server&lt;/h2&gt;
&lt;p&gt;We are using service account to generate access token in server to avoid user login process.&lt;/p&gt;
&lt;h3&gt;Node.js Server Implementation (Part)&lt;/h3&gt;
&lt;p&gt;Install Google API Client Library&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm install --save googleapis
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Import service account key&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let privateKey = require(&quot;./google_key.json&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Return Google access token to client&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// https://your-domain/accessTokens will return access tokens such as google access tokens
app.get(&quot;/accessTokens&quot;, (req, res) =&amp;gt; {
  let { google } = require(&quot;googleapis&quot;);
  let privateKey = require(&quot;./google_key.json&quot;);

  // configure a JWT auth client
  let jwtClient = new google.auth.JWT(
    privateKey.client_email,
    null,
    privateKey.private_key,
    &quot;https://www.googleapis.com/auth/analytics.readonly&quot;,
  );

  jwtClient.authorize(function (err, token) {
    if (err) {
      console.log(err);
      return res.status(500).send(&quot;Error&quot;);
    } else {
      return res.send(token.access_token);
    }
  });
});
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Python Server Implementation (Part)&lt;/h3&gt;
&lt;p&gt;Install Google API Client Library&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo pip install --upgrade google-api-python-client
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Return Google access token to client&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# service-account.py

from oauth2client.service_account import ServiceAccountCredentials

# The scope for the OAuth2 request.
SCOPE = &apos;https://www.googleapis.com/auth/analytics.readonly&apos;

# The location of the key file with the key data.
KEY_FILEPATH = &apos;path/to/json-key.json&apos;

# Defines a method to get an access token from the ServiceAccount object.
def get_access_token():
  return ServiceAccountCredentials.from_json_keyfile_name(
      KEY_FILEPATH, SCOPE).get_access_token().access_token
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;6. Load Google Analytics Embed API library&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;script&amp;gt;
  (function (w, d, s, g, js, fs) {
    g = w.gapi || (w.gapi = {});
    g.analytics = {
      q: [],
      ready: function (f) {
        this.q.push(f);
      },
    };
    js = d.createElement(s);
    fs = d.getElementsByTagName(s)[0];
    js.src = &quot;https://apis.google.com/js/platform.js&quot;;
    fs.parentNode.insertBefore(js, fs);
    js.onload = function () {
      g.load(&quot;analytics&quot;);
    };
  })(window, document, &quot;script&quot;);
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;7. Add dashboard containers&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div id=&quot;chart-1-container&quot;&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;div id=&quot;chart-2-container&quot;&amp;gt;&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;8. Fetch Google access token and load dashboards&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;script&amp;gt;
  gapi.analytics.ready(function () {
    fetch(&quot;/api/accessTokens&quot;)
      .then(function (response) {
        return response.text();
      })
      .then(function (accessToken) {
        gapi.analytics.auth.authorize({
          serverAuth: {
            access_token: accessToken,
          },
        });
        dataChart1.execute();
        dataChart2.execute();
      });

    var dataChart1 = new gapi.analytics.googleCharts.DataChart({
      query: {
        ids: &quot;ga:00000000&quot;, // &amp;lt;-- Replace with the ids value for your view.
        &quot;start-date&quot;: &quot;90daysAgo&quot;,
        &quot;end-date&quot;: &quot;today&quot;,
        metrics: &quot;ga:sessions,ga:users&quot;,
        dimensions: &quot;ga:date&quot;,
      },
      chart: {
        container: &quot;chart-1-container&quot;,
        type: &quot;LINE&quot;,
        options: {
          width: &quot;100%&quot;,
        },
      },
    });

    var dataChart2 = new gapi.analytics.googleCharts.DataChart({
      query: {
        ids: &quot;ga:00000000&quot;, // &amp;lt;-- Replace with the ids value for your view.
        &quot;start-date&quot;: &quot;90daysAgo&quot;,
        &quot;end-date&quot;: &quot;today&quot;,
        metrics:
          &quot;ga:pageviews,ga:uniquePageviews,ga:timeOnPage,ga:bounces,ga:entrances,ga:exits&quot;,
        sort: &quot;-ga:pageviews&quot;,
        dimensions: &quot;ga:pagePath&quot;,
        &quot;max-results&quot;: 10,
      },
      chart: {
        container: &quot;chart-2-container&quot;,
        type: &quot;PIE&quot;,
        options: {
          width: &quot;100%&quot;,
          pieHole: 0.4,
        },
      },
    });
  });
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;References:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://ga-dev-tools.appspot.com/embed-api/server-side-authorization/&quot;&gt;Google Analytics Embed API - Server-side Authorization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.google.com/analytics/devguides/reporting/embed/v1/component-reference&quot;&gt;Google Analytics Embed API - Built-in Components Reference&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><dc:language>en</dc:language><category>Web</category><category>Analytics</category></item><item><title>Why we need to deprecate x prefix for HTTP headers?</title><link>https://tonyxu.io/blog/http-deprecate-x-prefix/</link><guid isPermaLink="true">https://tonyxu.io/blog/http-deprecate-x-prefix/</guid><description>A concise explanation of RFC 6648 and why custom HTTP headers should stop using the X- prefix.</description><pubDate>Wed, 01 Aug 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In June 2012, the Internet Engineering Task Force published &lt;a href=&quot;https://tools.ietf.org/html/rfc6648&quot;&gt;RFC 6648&lt;/a&gt;, recommending that custom HTTP headers stop using the &lt;code&gt;X-&lt;/code&gt; prefix. LinkedIn also used this convention, so I read the RFC and wanted to explain why the recommendation changed.&lt;/p&gt;
&lt;h2&gt;X- prefix background&lt;/h2&gt;
&lt;p&gt;HTTP header is used to transmit additional information between client and server.&lt;/p&gt;
&lt;p&gt;Some standard HTTP header:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Authorization&lt;/code&gt;: Often used to transmit OAuth access token or other authorization information. e.g. &lt;code&gt;Authorization: Bearer ABCDEFG&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Content-Type&lt;/code&gt;: Often used to represent media type in request body. e.g. &lt;code&gt;application/x-www-form-urlencoded&lt;/code&gt; or &lt;code&gt;application/json&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;User-Agent&lt;/code&gt;: Browser identifier. e.g. &lt;code&gt;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If people want to have custom header, &lt;code&gt;X-&lt;/code&gt; prefix is suggested to avoid conflict. This recommendation is raised in 1982 for Email standard(&lt;a href=&quot;https://tools.ietf.org/html/rfc822&quot;&gt;RFC-822&lt;/a&gt;)，working fine for decades。&lt;/p&gt;
&lt;h2&gt;Usage of X- prefix&lt;/h2&gt;
&lt;p&gt;Among all non-standard HTTP headers, some become very popular:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;X-Forwarded-For&lt;/code&gt;: Mark origin IP of client connecting to server through proxy&lt;/li&gt;
&lt;li&gt;&lt;code&gt;X-Forwarded-Host&lt;/code&gt;: Mark origin host of client connecting to server through proxy&lt;/li&gt;
&lt;li&gt;&lt;code&gt;X-Forwarded-Proto&lt;/code&gt;: Mark protocol of client connecting to server through proxy&lt;/li&gt;
&lt;li&gt;&lt;code&gt;X-Powered-By&lt;/code&gt;: Mark framework, technology, environment, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;X- prefix issues&lt;/h2&gt;
&lt;p&gt;When these &lt;code&gt;X-&lt;/code&gt; prefix become more and more popular, it&apos;s tough to handle it when we need to standardize them. In theory, we should remove the &lt;code&gt;X-&lt;/code&gt; prefix after standardize it, but it will apparently affect existing applications. To avoid backward-compatibility issues, we have to keep it. In summary, the &lt;code&gt;X-&lt;/code&gt; prefix can&apos;t identify between standard and non-standard headers anymore.&lt;/p&gt;
&lt;h2&gt;Solutions&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;No longer recommend &lt;code&gt;X-&lt;/code&gt; for new custom headers, and no longer use &lt;code&gt;X-&lt;/code&gt; prefix to distinguish standard and non-standard headers&lt;/li&gt;
&lt;li&gt;If it&apos;s possible for new custom header to be standardized, use a non-used and meaningful header name&lt;/li&gt;
&lt;li&gt;If it&apos;s not possible for new custom header to be standardized, include organization name (e.g. reverse domain name &lt;code&gt;com.example.foo&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;No recommendation to keep/drop for existing custom HTTP headers&lt;/li&gt;
&lt;li&gt;&lt;code&gt;X-&lt;/code&gt; prefix can&apos;t be used to assume safety of headers&lt;/li&gt;
&lt;/ol&gt;
</content:encoded><dc:language>en</dc:language><category>Web</category><category>Engineering</category></item><item><title>Ultimate way to beautify Mac terminal (oh-my-zsh) and plugin recommendations</title><link>https://tonyxu.io/blog/ultimate-way-to-beautify-mac-terminal-and-recommendations-for-plugins/</link><guid isPermaLink="true">https://tonyxu.io/blog/ultimate-way-to-beautify-mac-terminal-and-recommendations-for-plugins/</guid><description>A macOS setup for improving Terminal with a profile, Oh My Zsh, themes, and practical plugins. Verify installation commands before use.</description><pubDate>Thu, 26 Jul 2018 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;Historical note: this guide reflects a 2018 macOS setup. The commands, default paths, and plugin URLs may have changed; verify them against the current project documentation.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If you use a Mac for development, Terminal is probably one of your most frequently used apps. This guide shows how I improved it with a custom profile, Oh My Zsh, a theme, and a small set of plugins.&lt;/p&gt;
&lt;h2&gt;We will be doing these for our Terminal&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Install Terminal Profile: Customize Terminal Color&lt;/li&gt;
&lt;li&gt;Install &lt;code&gt;oh-my-zsh&lt;/code&gt;: Use the powerful &lt;code&gt;zsh&lt;/code&gt; shell in Terminal&lt;/li&gt;
&lt;li&gt;Install &lt;code&gt;oh-my-zsh&lt;/code&gt; themes: Beautify &lt;code&gt;oh-my-zsh&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Install useful &lt;code&gt;oh-my-zsh&lt;/code&gt; plugins: Add shortcuts and quality-of-life improvements&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Preparation&lt;/h2&gt;
&lt;p&gt;Recommend to install &lt;code&gt;homebrew&lt;/code&gt; first:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/usr/bin/ruby -e &quot;$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Install zsh if you are on macOS version prior to Catalina:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Install zsh
brew install zsh
# Set zsh as your default shell
chsh -s /usr/local/bin/zsh
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Install Terminal Profile&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Go to &lt;a href=&quot;https://github.com/lysyi3m/osx-terminal-themes&quot;&gt;osx-terminal-theme&lt;/a&gt; and download your favorite theme in &lt;code&gt;scheme&lt;/code&gt; folder&lt;/li&gt;
&lt;li&gt;Double click the theme file to install and set as default&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Feel free to use my Terminal Profile if you would like to try: https://gist.github.com/tonyxu-io/6b845cb1a53622eb4f1ce4063365e427&lt;/p&gt;
&lt;h2&gt;Install oh-my-zsh&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Oh My Zsh is a delightful, open source, community-driven framework for managing your Zsh configuration. It comes bundled with thousands of helpful functions, helpers, plugins, themes, and a few things that make you shout...&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Install &lt;code&gt;oh-my-zsh&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sh -c &quot;$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Install oh-my-zsh theme&lt;/h2&gt;
&lt;h3&gt;Built-in themes&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;oh-my-zsh&lt;/code&gt; provides some built-in themes which you can immediately use:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Find your favorite theme in built-in themes list: https://github.com/robbyrussell/oh-my-zsh/wiki/Themes&lt;/li&gt;
&lt;li&gt;Set &lt;code&gt;ZSH_THEME&lt;/code&gt; to your favorite theme name in &lt;code&gt;~/.zshrc&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Activate setting by &lt;code&gt;source ~/.zshrc&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Third-party themes&lt;/h3&gt;
&lt;p&gt;There are more third-party themes developed for &lt;code&gt;oh-my-zsh&lt;/code&gt;; find and install them here:&lt;/p&gt;
&lt;p&gt;https://github.com/robbyrussell/oh-my-zsh/wiki/External-themes&lt;/p&gt;
&lt;h2&gt;Install oh-my-zsh must-have plugins&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;oh-my-zsh&lt;/code&gt; has many powerful plugins, below are some must-have plugins that will boost your productivity.&lt;/p&gt;
&lt;p&gt;Sample config:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# ~/.zshrc:
plugins=(
  git
  extract
  autojump
  zsh-autosuggestions
  zsh-syntax-highlighting
)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;git&lt;/h3&gt;
&lt;p&gt;Built-in，use abbreviations for git commands, e.g. &lt;code&gt;gaa&lt;/code&gt; -&amp;gt; &lt;code&gt;git add --all&lt;/code&gt;, use &lt;code&gt;alias | grep git&lt;/code&gt; to get all abbreviations commands&lt;/p&gt;
&lt;p&gt;Activate: Add &lt;code&gt;git&lt;/code&gt; to &lt;code&gt;~/.zshrc&lt;/code&gt; plugins list.&lt;/p&gt;
&lt;h3&gt;extract&lt;/h3&gt;
&lt;p&gt;Built-in, no need to use complicated &lt;code&gt;tar&lt;/code&gt; to extract zip files&lt;/p&gt;
&lt;p&gt;Activate: Add &lt;code&gt;extract&lt;/code&gt; to the &lt;code&gt;~/.zshrc&lt;/code&gt; plugins list.&lt;/p&gt;
&lt;p&gt;Usage: &lt;code&gt;extract file_name&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;autojump&lt;/h3&gt;
&lt;p&gt;Use &lt;code&gt;j&lt;/code&gt; to quickly jump to a folder, e.g. &lt;code&gt;j Downloads&lt;/code&gt; -&amp;gt; &lt;code&gt;cd ~/Downloads&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Install: &lt;code&gt;brew install autojump&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Activate: Add &lt;code&gt;autojump&lt;/code&gt; to &lt;code&gt;~/.zshrc&lt;/code&gt; plugins list.&lt;/p&gt;
&lt;h3&gt;zsh-syntax-highlighting&lt;/h3&gt;
&lt;p&gt;Commands syntax highlight plugin&lt;/p&gt;
&lt;p&gt;Install: &lt;code&gt;git clone https://github.com/zsh-users/zsh-syntax-highlighting ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Activate: Add &lt;code&gt;zsh-syntax-highlighting&lt;/code&gt; to &lt;code&gt;~/.zshrc&lt;/code&gt; plugins list.&lt;/p&gt;
&lt;h3&gt;zsh-autosuggestions&lt;/h3&gt;
&lt;p&gt;Auto complete commands by typing →&lt;/p&gt;
&lt;p&gt;Install: &lt;code&gt;git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Activate: Add &lt;code&gt;zsh-autosuggestions&lt;/code&gt; to the &lt;code&gt;~/.zshrc&lt;/code&gt; plugins list.&lt;/p&gt;
&lt;h2&gt;My own ~/.zshrc config&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# Path to your oh-my-zsh installation.
export ZSH=/Users/tonxu/.oh-my-zsh

# theme
ZSH_THEME=&quot;robbyrussell&quot;

# plugins
plugins=(
  git
  extract
  autojump
  zsh-autosuggestions
  zsh-syntax-highlighting
)

source $ZSH/oh-my-zsh.sh

# set language
export LANG=en_US.UTF-8

# default editor
export EDITOR=&apos;vi&apos;

# ssh key path
export SSH_KEY_PATH=&quot;~/.ssh/rsa_id&quot;
&lt;/code&gt;&lt;/pre&gt;
</content:encoded><dc:language>en</dc:language><category>macOS</category><category>Tools</category></item><item><title>OAuth 2.0 Authorization Code Flow with PKCE for Native Apps</title><link>https://tonyxu.io/blog/oauth2-pkce-flow/</link><guid isPermaLink="true">https://tonyxu.io/blog/oauth2-pkce-flow/</guid><description>Why native and other public OAuth clients use the authorization code flow with PKCE, with a browser-based S256 implementation.</description><pubDate>Tue, 24 Jul 2018 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;The original insecure random verifier has been replaced with &lt;code&gt;crypto.getRandomValues&lt;/code&gt; and Web Crypto SHA-256. Provider details can still change, so verify current OAuth and PKCE documentation before using the examples.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If you are building a native application and need OAuth 2.0, PKCE is the recommended authorization-code flow for public clients. This article explains why.&lt;/p&gt;
&lt;p&gt;Native application is often used to refer to native application that has no back-end, and running totally in user&apos;s devices such as Windows, Mac, iOS, and Android, where securely storing secrets is impossible.&lt;/p&gt;
&lt;p&gt;What are the OAuth 2 options for those native applications and what are the pros and cons for them?&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Implicit Flow: Implicit flow will pass &lt;code&gt;Access Token&lt;/code&gt; to Redirect URL。Assume your native application is redirecting to third-party browsers to perform OAuth2 authorization request, then your application either obtain the &lt;code&gt;Access Token&lt;/code&gt; back by listening to &lt;code&gt;app-name://?access_token=&lt;/code&gt; request or start a HTTP server to listen to &lt;code&gt;http://localhost:{port}/?access_token=&lt;/code&gt; request. These two approaches both have the risk of &lt;code&gt;Access Token&lt;/code&gt; being intercepted by malicious party who occupy URL Scheme or localhost port. Also access token can&apos;t be renewed after expiration. Thus implicit flow is not recommended.&lt;/li&gt;
&lt;li&gt;Authorization Code Flow: &lt;code&gt;Access Token&lt;/code&gt; of this flow will not be passed to &lt;code&gt;Redirect URL&lt;/code&gt; directly. &lt;code&gt;Redirect URL&lt;/code&gt; will only receive an &lt;code&gt;authorization code&lt;/code&gt;，which need to be used along with &lt;code&gt;Client ID&lt;/code&gt;，and &lt;code&gt;Client Secret&lt;/code&gt; to exchange for &lt;code&gt;Access Token&lt;/code&gt;. Since native application can&apos;t securely store &lt;code&gt;Client Secret&lt;/code&gt;, malicious party can decode it from native code/binary, and intercept &lt;code&gt;Authorization Code&lt;/code&gt; to exchange for &lt;code&gt;Access Token&lt;/code&gt;. Thus authorization code flow is not recommended either. Even some OAuth provider doesn&apos;t require &lt;code&gt;Client Secret&lt;/code&gt;, &lt;code&gt;Access Token&lt;/code&gt; can still be exchanged by malicious party.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now that two options are excluded, how can native application securely implement OAuth2? The answer is PKCE OAuth 2.0.&lt;/p&gt;
&lt;p&gt;PKCE (Proof Key for Code Exchange), is using cryptography method to prevent malicious party to be able to exchange access token with the information they can intercept.&lt;/p&gt;
&lt;p&gt;PKCE flow steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Generate random string and encode with URL-Safe Base64, and used as &lt;code&gt;code_verifier&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Do SHA256 hash，and URL-Safe Base64，and used as &lt;code&gt;code_challenge&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Redirect to OAuth provider with &lt;code&gt;code_challenge&lt;/code&gt; and receive &lt;code&gt;Authorization Code&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Exchange for &lt;code&gt;Access Token&lt;/code&gt; with &lt;code&gt;code_verifier&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Since malicious party can&apos;t infer &lt;code&gt;code_verifier&lt;/code&gt; by &lt;code&gt;code_challenge&lt;/code&gt;, only the native application itself knows about the two value. In this way, even if malicious party intercepted &lt;code&gt;code_challenge&lt;/code&gt;, it will not be able to exchange &lt;code&gt;Access Token&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Generate PKCE Code Verifier and Code Challenge Online&lt;/h2&gt;
&lt;p&gt;Use the compact &lt;a href=&quot;https://tonyxu.io/tools/pkce-generator/&quot;&gt;PKCE code verifier and challenge generator&lt;/a&gt; to create a verifier and its S256 challenge locally in your browser.&lt;/p&gt;
&lt;h2&gt;Implementation (JavaScript)&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!doctype html&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;script&amp;gt;
      function base64URL(bytes) {
        var binary = &quot;&quot;;
        bytes.forEach(function (byte) {
          binary += String.fromCharCode(byte);
        });
        return btoa(binary)
          .replace(/=/g, &quot;&quot;)
          .replace(/\+/g, &quot;-&quot;)
          .replace(/\//g, &quot;_&quot;);
      }
      function generateCodeVerifier() {
        var randomBytes = new Uint8Array(32);
        crypto.getRandomValues(randomBytes);
        var code_verifier = base64URL(randomBytes);
        document.getElementById(&quot;code_verifier&quot;).value = code_verifier;
      }
      async function generateCodeChallenge(code_verifier) {
        var data = new TextEncoder().encode(code_verifier);
        var digest = await crypto.subtle.digest(&quot;SHA-256&quot;, data);
        return base64URL(new Uint8Array(digest));
      }
      async function submit() {
        var code_verifier = document.getElementById(&quot;code_verifier&quot;).value;
        var code_challenge = await generateCodeChallenge(code_verifier);
        document.getElementById(&quot;code_challenge&quot;).textContent = code_challenge;
        document.getElementById(&quot;code_challenge_div&quot;).style.display = &quot;block&quot;;
      }
    &amp;lt;/script&amp;gt;
  &amp;lt;/head&amp;gt;

  &amp;lt;body&amp;gt;
    &amp;lt;div&amp;gt;
      &amp;lt;label for=&quot;code_verifier&quot;&amp;gt;Code Verifier: &amp;lt;/label&amp;gt;
      &amp;lt;input type=&quot;text&quot; id=&quot;code_verifier&quot; name=&quot;code_verifier&quot; size=&quot;50&quot; /&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;br /&amp;gt;
    &amp;lt;div style=&quot;display:none&quot; id=&quot;code_challenge_div&quot;&amp;gt;
      Code Challenge:
      &amp;lt;span id=&quot;code_challenge&quot;&amp;gt; &amp;lt;/span&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;br /&amp;gt;
    &amp;lt;div&amp;gt;
      &amp;lt;button onclick=&quot;generateCodeVerifier()&quot;&amp;gt;Generate Code Verifier&amp;lt;/button&amp;gt;
      &amp;lt;button onclick=&quot;submit()&quot;&amp;gt;Generate Code Challenge&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;OAuth2 providers that support PKCE&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.google.com/identity/protocols/OAuth2InstalledApp&quot;&gt;OAuth 2.0 for Mobile &amp;amp; Desktop Apps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-protocols-oauth-code&quot;&gt;Authorize access to Azure Active Directory web applications using the OAuth 2.0 code grant flow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.okta.com/authentication-guide/implementing-authentication/auth-code-pkce&quot;&gt;Implementing the Authorization Code Flow with PKCE&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;p&gt;Reference:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://tools.ietf.org/html/rfc7636&quot;&gt;RFC 7636 - OAuth PKCE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tools.ietf.org/html/rfc8252&quot;&gt;RFC 8252 - OAuth 2.0 for Native Apps&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><dc:language>en</dc:language><category>Web</category><category>Security</category></item></channel></rss>