Home 中文

Sometimes, I like to make stuff.

Some are useful, others are utterly useless.

But all are good fun.

  • Saladict

    Github Stars Chrome Web Store Users Chrome Web Store Rating Mozilla Add-on Users Mozilla Add-on Rating

    A handy dictionary extension with eye-pleasing UI. Praised(Chrome review / Firefox review) and supported by hundreds of thousands of users.

    Highlights in terms of functional design:

    1. Results from different dictionaries are integrated into one panel with consistent styles for easy cross-reference.
    2. Rapid searching with multiple search modes plus different profiles.
    3. Search text contexts as well as translations are kept in notebook.
    4. High accessibility. Inside iframes, PDFs and even outside of browser.
    5. Follow Unix philosophy. Focus on experience on looking up words while offering flexible interface for force multiplier effects with other tools.

    Highlights in terms of technical implementation:

    1. Mass use of React Hooks for abstracting Component async UI logic, with RxJS handling complex user inputs(See my other project observable-hooks).
    2. Components are built with Storybook which enables rapid UI development.
    3. Syltes of dictionary panel and each dictionary are isolated with Shadow DOM with lower cost of performance.
    4. Automation are introduced into the build process(with my other project neutrino-webextension). Dictionaries are loaded with a plugin mechanism.
    [ Read More ]
  • Observable Hooks

    Github Stars NPM Downloads Total NPM Downloads Monthly

    React hooks for RxJS Observables with super flexible APIs.


    • Component specific async logic, which are reused with the Component, no longer needs to be delegated to stateful parent or state management libraries.
    • With React Hooks, logic can be encapsulated nicely together for easy testing.
    • RxJS comes with a mature and abundant ecosystem which can address a wide range of async problems.


    • Simple yer powerful API. Not only easier to use but also simpler to implement and faster to run.
    • States, Props and Observables can interconvert into each other seamlessly.
    • Observables can be operated directly, whether they are hooks generated or from outside of the Component.
    • Operations on Observables are pure just like Epic in Redux Observable which can be reused and isolated for testing.
    • Supports Render-as-You-Fetch pattern with Suspense.
    • Fully tested. Stable API.
    [ Read More ]
  • PostCSS Safe Important

    Github Stars NPM Downloads Total NPM Downloads Monthly

    PostCSS plugin that adds !important to style declarations safely. Used and recommended by many large projects like Uppy, stylelint, vmd and HoverCards.

    1. Accuracy. Unlike other regex based implementations, this plugin uses AST (Abstract Syntax Tree) generated by PostCSS to accurately locate rules.
    2. Safety. Adding !important to every declarations might break styles. This plugin will skip unnecessary declarations.
    3. Configurability. Flexible and fine-grained control over the plugin.
    [ Read More ]
  • Side Effect Manager

    Github Stars NPM Downloads Total NPM Downloads Monthly

    A tiny library to encapsulate side effects in a compact, reusable and testable style.

  • Webextension Store Meta

    Github Stars NPM Downloads Total NPM Downloads Monthly

    Get browser extension(webextension) item meta from Chrome Web Store and Firefox add-ons. Used by Shields.io and Badgen.

  • Neutrino WebExtension

    Github Stars

    Neutrino 9 preset for WebExtension development with hot reload and framework devtools.

    Zero upfront configuration necessary to start developing and building a WebExtension.

    Run development mode in a fake WebExtension environment which supports hot reload and framework devtools.

    Webpack chunks are translated into manifest configs nicely.

    Outputs are bundled for each browser respectively, with different manifest.

    Works well with other official Neutrino presets.

    [ Read More ]
  • Webpack Target WebExtension

    Github Stars NPM Downloads Total NPM Downloads Monthly

    WebExtension Target for Webpack 4. Supports code-splitting with native dynamic import.

    Dynamically loading chunks is not possible in WebExtension content scripts with the default Webpack JSONP.

    This library is also included in the neutrino-webextension preset.

    [ Read More ]
  • Hexo Filter Github Emojis

    Github Stars NPM Downloads Total NPM Downloads Monthly

    A Hexo plugin that adds emoji support, using Github Emojis API.

    With accessibility in mind, this plugin generates unicodes for emojis then makes the font transparent and displays emoji images with background-image.

    [ Read More ]
  • React Resize Reporter

    Github Stars NPM Downloads Total NPM Downloads Monthly

    Lightweight React Component that reports width and height changes when its parent resizes.


    1. Currently there is no perfect solution for detecting element resizing.
    2. Existing solutions are either buggy or with verbose API.


    1. Clean API.
    2. Two implementations with same interface.
    [ Read More ]
  • Get Selection More

    Github Stars NPM Downloads Total NPM Downloads Monthly

    Get text and context (sentence, paragraph...) from window.getSelection().


    Github Stars

    A technical blog following JAMstack architecture, based on GatsbyJS, a React Framework using GraphQL to manage resources. Post contents are managed on Netlify CMS. The whole site is delivered via Netlify network.

    This is also an attempt to replace Class components with React Hooks, which brings great convenience and pleasant development experience.

    Managing data and resources with GraphQL is also powerful and dead easy.

    With Netlify CMS and Utterances, post files and comments are stored back to Github which reduces the dependency of third-party services.

    Site logo are designed with illustrator. Social media icons are taken from NViconsLib 2, edited with Boxy SVG, merged with IcoMoon and compressed with SVGOMG.

    [ Read More ]
  • Retux

    Github Stars

    Minimalist declarative type-safe(strongly-typed) scalable TypeScript Redux architecture.


    • Minimalist. Leveraging advanced features of TypeScript Retux reduces boilerplate code with better type-inferring and auto-completion.
    • Declarative. Action-First instead of Action-Creator-Fisrt desgin results in code that is clean and easy to read for new contributors and future-self.
    • Type-safe(strongly-typed). Retux enforces strict typings. With the utilities in Retux you will never lose the strictness of typings while enjoying great flexibility.
    • Scalable. A Retux module can be easily split into isomorphic sub-modules. Retux can also optionally leverage the power of meta-programming on modern engine for further performance boost.
    [ Read More ]
  • Use Suspensible

    Github Stars NPM Downloads Total NPM Downloads Monthly

    React hooks that can make any data suspensible.


    If you follow the Relay Suspense pattern you need to add wrappers to async logic then use read() to get data in Components.

    This means:

    • It can only apply to Promise based async logic.
    • You have to write logic and use data in a specific way.
    • When you successfully read() a piece of data, it means the data is "fetched" but not necessary "usable"(unless you write business logic in a conventional way to make sure they are the same). You still need to add logic to check e.g. variation/validation of the data.

    use-suspensible does not care how you implement the business logic. It only cares about if the data is usable or not. This makes it a universal solution for Suspense.

    With use-suspensible you simply fetch and use data as usual/you like. It just works (with almost no cost).

    [ Read More ]
  • WeiTweet

    Github Stars Chrome Web Store Users Chrome Web Store Rating Mozilla Add-on Users Mozilla Add-on Rating

    Chrome / Firefox extension. Share Fanfou, Twitter and Weibo in one click.

    1. Abstract OAuth 1a & 2 flows using template design pattern to support different platforms(OAuth 1a with Fanfou and Twitter, Oauth 2 with Weibo).
    2. Serverless OAuth flow with chrome.identity and content script magic.
    3. UI with iview.
    4. Build system is vue-cli based and extended with webpack-chain, which enables building and packing in one click.
    [ Read More ]
  • Release Notifier for Github

    Github Stars Chrome Web Store Users Chrome Web Store Rating Mozilla Add-on Users Mozilla Add-on Rating

    Chrome / Firefox extension for watching Github releases.

    Unofficial "polyfill" for watching Github releases. It was based on this lovely idea. A year later Github finally added basic official support.

    It uses Github APIs and takes advantage of 304 cache.


    [ Read More ]
  • JavaScript 30

    30-day vanilla JS coding challenge. Inspired by Wes Bos's JavaScript 30.

    Some of my interesting ideas:

    [ Read More ]
  • This Project

    NUXT based static website.

    With SSR generated static pages, DOM can be rendered before JavaScript loading, after which Vue will take over DOM manipulation and routing is controled by Vue-router.


    Common parts of each project description are abstracted and resued. Adding a new project description can be achieved with minimum configuration.

    Nuxt-i18n overrides Nuxt default routes and adds locale prefixes to every URL. Description of each project is written in Markdown and transformed to HTML via markdown-loader.

    [ Read More ]
  • Leetmark

    Chrome Web Store Users Chrome Web Store Rating

    A Chrome extension that can generate a decent Github Flavored Markdown template from a Leetcode problem page.

    Meta data is stored as Front Matter from which Github will generate a neat data table.

  • Empty Module Loader

    NPM Downloads Total NPM Downloads Monthly

    A webpack loader that replaces module with empty function which can be eliminated with Webpack Tree Shaking.