Commerce.js v3: the next major release
See original GitHub issueAs we prepare for our next major release of Commerce.js (v3), we would like to hear from you, the community, and users of our product.
With Commerce.js v3 we want to continue making it even easier to build headless eCommerce websites, apps, mobile apps, IoT smart device software, etc. Reducing pain points, code duplication, complexities of connecting libraries and frameworks together, and overall; interacting with the Chec API quickly and easily.
We’ll start by sharing a few things that we want to include in the next release of our open-source eCommerce SDK, and welcome you to react to this post, and post comments with your own suggestions, feedback, or questions.
📅 Background
Commerce.js has been around for a number of years now via a hosted CDN file that could be easily embedded into any HTML web page. This was great in the age of jQuery, or if you wanted to drop in an embeddable checkout into your WordPress blog or something, but the web landscape changes rapidly. We retrospectively tagged version 1.0.0 on 9 Oct 2019, in order to let our developers install the package via NPM.
We shipped version 2.0 of Commerce.js on 14 Jan 2020. The primary motivations for version 2.0 were:
- Change from callback functions to returning promises
- Unpack object arguments into individual arguments in method signatures
- Re-frame installation process priority from embedding a CDN script tag to using NPM
- Modernise the build chain, add unit tests, etc
v3 improvement ideas
💡 Add support for checkout-level integrations
An example of this might be using a third party tax or shipping provider, which would run asynchronously after your checkout token has been generated, then automatically update your checkout token with adjusted totals when it needs to. Ideally the developer doesn’t need to do much for this to work, and merchants can easily enable these integrations in the dashboard without requiring developer interaction.
💡 Modern library (ESM) bundle
Using Commerce.js today involves import Commerce from '@chec/commerce.js'
then using the Commerce object, which includes all Commerce.js APIs in one object. We want to add more modular exports, so you could use individual parts of the SDK, e.g. import { products } from '@chec/commerce.js'
.
This will help developers keep their bundled application sizes small, and in some cases (e.g. Angular 10) will issue warnings for building your application without these kinds of imports. We want to offer a variety of different bundle formats to suit different consumers.
💡 Handle API versioning gracefully
The Chec API’s latest version is considered bleeding edge, and breaking changes are added with a new date based version that contains backwards compatibility adapters to preserve API integrity. More info on our versioning system here. Your Chec API keys also have an API version attached to them, which is assigned automatically the first time you use your API key.
Commerce.js allows developers to customise the API version that is used by modifying the config
object in the Commerce constructor. We would like to add better support for individual APIs within the SDK to use different API versions, support for multiple API key profiles (and versions) that can be easily switched, and a method that allows the semantic versioning used in Commerce.js to be more compatible with the date-based (non semver) versioning system we use in our API. This will be especially important when combined with TypeScript definitions which are adjusted to suit the API but released under semver.
💡 Native TypeScript support
We offer TypeScript definitions today via the third-party DefinitelyTyped repository: https://www.npmjs.com/package/@types/chec__commerce.js. In Commerce.v3 we would like to rebuild the SDK from the ground up with native TypeScript support. Coupled with the previous improvement (Handle API versioning gracefully), this will be critical to ensure that developers using Commerce.js will send the appropriate API request structure for their TypeScript definitions, and receive the appropriate API response from the Chec API for their TypeScript definitions.
Bundling TypeScript definitions into Commerce.js, rather than publishing them to a separate repository, will make this process more streamlined. In future our API documentation may provide an OpenAPI schema which could be used to generate these types also, which allows scope for a neat build pipeline to keep all of these parts in sync.
💡 Revamp the console debugger
When you have debug mode enabled, Commerce.js gives you a console debugger in your browser or terminal. A number of improvements could be made here:
- Remove debug metadata from the API, since it isn’t available on every endpoint, and add it to Commerce.js
- Rebuild ANSI colour support, adding support for dark mode in browsers
- See whether uncaught promise exceptions can be handled more gracefully to prevent console pollution
💡 Auto-select county/state field when postal/zip is entered
If a customer enters a postal/ZIP code into a checkout form that is recognised (this will probably be mainly US-based initially), we should be able to automatically select the county/state that is appropriate. For example, you enter 94107, we auto-select California.
💡 Prevent unnecessary network requests
Commerce.js currently performs a number of unnecessary network requests, for example: validation errors when we know request structures are incomplete. TypeScript support will help to prevent this, but we cannot yet expect all developers to use TypeScript. There are also some instances of network requests that clearly shouldn’t happen, e.g. GET /v1/checkouts/undefined/token
, and there are cases where multiple API requests are performed in quick succession to the same endpoint.
💡 Support optimistic UI updates
When building a cart, you will list the line items in your cart with buttons to increase/decrease the quantity, a button to delete line items, then a summary of the cart totals. If you bind any of these buttons to Commerce.js SDK methods (like commerce.cart.add()
), and have the cart object bound to the state that controls your UI, you will need to wait for the API to respond before your quantity changes from 1 to 2.
Ideally, Commerce.js has built-in support for optimistic UI updates, so that when you click to increase your quantity the item quantity and totals update immediately, then roll back if the API request fails for some reason. The same would be said for deleting items from your cart. Again, using TypeScript would make this easier, as we would know the data structure of the line item to optimistically push into state.
It’s possible that achieving this might involve introducing native state management. If this were to happen, we would likely create an abstraction layer over whichever state management library (e.g. Redux, custom-made) we chose to implement. Implications of this might mean that instead of binding your UI components to the response of commerce.cart.retrieve()
, or the cart
object in your state, you would instead bind it to commerce.state.cart
, which Commerce.js would update as necessary.
💡 Real-time updates with WebSockets
The first improvement in this list is to add support for checkout-level integrations and would involve an asynchronous update of your checkout tokens when things change in the background. There will be a number of ways to achieve this, but one option is to use WebSockets to allow the Chec API to push new checkout tokens, or a notification of change to your existing checkout token in order for it to be re-fetched for you, directly to your customer’s browser.
Adding native support for WebSockets in Commerce.js has a number of other potential benefits, for example:
- Visibility over who is using your checkout in real-time
- Ability to update your customer’s checkouts, e.g. add items, apply discounts, etc
- Send customer support messages customers (via an abstracted WebSocket API layer in Commerce.js)
- Cancel a cart, e.g. if you realise a product is being sold that you don’t want to allow
- Reduced API traffic, since the API gives you new information when it changes, rather than having to ask for it (long polling)
- Real-time inventory updates for high demand products
Browser support for the WebSocket API is pretty strong in 2021.
Update: we are not planning on implementing this for the first phase of Commerce.js 3.0.
💡 Improved customer recognition
If your customers are authenticated in Commerce.js, we would like to add support for auto-filling the customer name, email address, phone number, shipping or billing address, and even support saved payment methods (via Stripe or Square).
👋 Get involved!
We want to hear from you! What do you hate about checkouts, either as a customer or a developer? What do you wish Commerce.js could do for you? Are there things you have to do every time you build a new project with Commerce.js?
Please feel free to react to this post, post comments, join our Slack community and chat with us, or tweet your suggestions.
You can also see a list of Commerce.js v3 ideas in our GitHub milestone.
Thanks for reading! We hope to hear from you soon.
Commerce.js
Email: hello@commercejs.com Web: https://commercejs.com Twitter: https://twitter.com/commercejs Slack: http://slack.commercejs.com
Issue Analytics
- State:
- Created 2 years ago
- Reactions:17
- Comments:10 (6 by maintainers)
Any thoughts on building a GraphQL API in the future?
Looking good. Excited for version 3 already 🚀
Optimistic UI updates
I really like the sounds of optimistic UI updates. Although I have a few questions:
1. Is this behaviour going to be for carts only, or other features as well?
2. To what extent will developers be able to opt-in/out of this behaviour? a) At a global level. Would a developer be able to disable the store entirely? And ideally not include any of the “store” code in their bundle? b) At a feature level. Would a developer be able to only use the behaviour for some cart actions? For example, if they wanted the optimistic updates for adding/removing cart items, but not for clearing the entire cart.
Server-side
It would also be great if all SDK methods were usable on the server-side. I think this is mostly true for the current SDK, except for some customer authentication methods.
Implementing the Commerce.js provider for Vercel’s commerce project required some of the “commerce” logic to be handled by Next.js API routes, and it was nice being able to write the Commerce.js code exactly as I would on the frontend (and share the same instance). Some of the login/logout didn’t work so well though, which I’ve described here: https://github.com/chec/commerce.js/issues/216.
A final thought would be about how this new state management/store concept (discussed above) would affect the server-side behaviour.
SDK method naming
Finally, a small comment about some of the current “checkout helper” SDK method names. A few of them are named
checkSomething
but they feel more likesetSomething
methods.For example,
checkDiscount
is used to actually apply the discount. I realise that the method does also “check” the validity of the discount code first, but I’ve always thought thatsetDiscount
would be more intuitive.https://commercejs.com/docs/sdk/checkout#check-discount-code https://commercejs.com/docs/sdk/checkout#check-shipping-method