Full Width [alt+shift+f] Shortcuts [alt+shift+k]
Sign Up [alt+shift+s] Log In [alt+shift+l]
21
We’ve just launched Hotwire Native v1.2 and it’s the biggest update since the initial launch last year. The update has several key improvements, bug fixes, and more API consistency between platforms. And we’ve created all new iOS and Android demo apps to show it off! A web-first framework for building native mobile apps Improvements There are a few significant changes in v1.2 that are worth specifically highlighting. Route decision handlers Hotwire Native apps route internal urls to screens in your app, and route external urls to the device’s browser. Historically, though, it wasn’t straightforward to customize the default behavior for unique app needs. In v1.2, we’ve introduced the RouteDecisionHandler concept to iOS (formerly only on Android). Route decisions handlers offer a flexible way to decide how to route urls in your app. Out-of-the-box, Hotwire Native registers these route decision handlers to control how urls are...
4 weeks ago

Improve your reading experience

Logged in users get linked directly to articles resulting in a better reading experience. Please login for free, it takes less than 1 minute.

More from 37signals Dev

Monitoring 10 Petabytes of data in Pure Storage

As the final part of our move out of the cloud, we are working on moving 10 petabytes of data out of AWS Simple Storage Service (S3). After exploring different alternatives, we decided to go with Pure Storage FlashBlade solution. We store different kinds of information on S3, from the attachments customers upload to Basecamp to the Prometheus long-term metrics. On top of that, Pure’s system also provides filesystem-based capabilities, enabling other relevant usages, such as database backup storage. This makes the system a top priority for observability. Although the system has great reliability, out-of-the-box internal alerting, and autonomous ticket creation, it would also be good to have our metrics and alerts to facilitate problem-solving and ensure any disruptions are prioritized and handled. For more context on our current Prometheus setup, see how we use Prometheus at 37signals. Pure OpenMetrics exporter Pure maintains two OpenMetrics exporters, pure-fb-openmetrics-exporter and pure-fa-openmetrics-exporter. Since we use Pure Flashblade (fb), this post covers pure-fb-openmetrics-exporter, although overall usage should be similar. The setup is straightforward and requires only binary and basic authentication installation. Here is a snippet of our Chef recipe that installs it: pure_api_token = "token" # If you use Chef, your token should come from an ecrypted databag. Changed to hardcoded here to simplify PURE_EXPORTER_VERSION = "1.0.13".freeze # Generally, we use Chef node metadata for version management. Changed to hardcoded to simplify directory "/opt/pure_exporter/#{PURE_EXPORTER_VERSION}" do recursive true owner 'pure_exporter' group 'pure_exporter' end # Avoid recreating under /tmp after reboot if target_binary is already there target_binary = "/opt/pure_exporter/#{PURE_EXPORTER_VERSION}/pure-fb-openmetrics-exporter" remote_file "/tmp/pure-fb-openmetrics-exporter-v#{PURE_EXPORTER_VERSION}-linux-amd64.tar.gz" do source "https://github.com/PureStorage-OpenConnect/pure-fb-openmetrics-exporter/releases/download/v#{PURE_EXPORTER_VERSION}/pure-fb-openmetrics-exporter-v#{PURE_EXPORTER_VERSION}-linux-amd64.tar.gz" not_if { ::File.exist?(target_binary) } end archive_file "/tmp/pure-fb-openmetrics-exporter-v#{PURE_EXPORTER_VERSION}-linux-amd64.tar.gz" do destination "/tmp/pure-fb-openmetrics-exporter-v#{PURE_EXPORTER_VERSION}" action :extract not_if { ::File.exist?(target_binary) } end execute "copy binary" do command "sudo cp /tmp/pure-fb-openmetrics-exporter-v#{PURE_EXPORTER_VERSION}/pure-fb-openmetrics-exporter /opt/pure_exporter/#{PURE_EXPORTER_VERSION}/pure-exporter" creates "/opt/pure_exporter/#{PURE_EXPORTER_VERSION}/pure-exporter" not_if { ::File.exist?(target_binary) } end tokens = <<EOF main: address: purestorage-mgmt.mydomain.com api_token: #{pure_api_token['token']} EOF file "/opt/pure_exporter/tokens.yml" do content tokens owner 'pure_exporter' group 'pure_exporter' sensitive true end systemd_unit 'pure-exporter.service' do content <<-EOU # Caution: Chef managed content. This is a file resource from #{cookbook_name}::#{recipe_name} # [Unit] Description=Pure Exporter After=network.target [Service] Restart=on-failure PIDFile=/var/run/pure-exporter.pid User=pure_exporter Group=pure_exporter ExecStart=/opt/pure_exporter/#{PURE_EXPORTER_VERSION}/pure-exporter \ --tokens=/opt/pure_exporter/tokens.yml ExecReload=/bin/kill -HUP $MAINPID SyslogIdentifier=pure-exporter [Install] WantedBy=multi-user.target EOU action [ :create, :enable, :start ] notifies :reload, "service[pure-exporter]" end service 'pure-exporter' Prometheus Job Configuration The simplest way of ingesting the metrics is to configure a basic Job without any customization: - job_name: pure_exporter metrics_path: /metrics static_configs: - targets: ['<%= @hostname %>:9491'] labels: environment: 'production' job: pure_exporter params: endpoint: [main] # From the tokens configuration above For a production-ready setup, we are using a slightly different approach. The exporter supports the usage of specific metric paths to allow for split Prometheus jobs configuration that reduces the overhead of pulling the metrics all at once: - job_name: pure_exporter_array metrics_path: /metrics/array static_configs: - targets: ['<%= @hostname %>:9491'] labels: environment: 'production' job: pure_exporter metric_relabel_configs: - source_labels: [name] target_label: ch regex: "([^.]+).*" replacement: "$1" action: replace - source_labels: [name] target_label: fb regex: "[^.]+\\.([^.]+).*" replacement: "$1" action: replace - source_labels: [name] target_label: bay regex: "[^.]+\\.[^.]+\\.([^.]+)" replacement: "$1" action: replace params: endpoint: [main] # From the tokens configuration above - job_name: pure_exporter_clients metrics_path: /metrics/clients static_configs: - targets: ['<%= @hostname %>:9491'] labels: environment: 'production' job: pure_exporter params: endpoint: [main] # From the tokens configuration above - job_name: pure_exporter_usage metrics_path: /metrics/usage static_configs: - targets: ['<%= @hostname %>:9491'] labels: environment: 'production' job: pure_exporter params: endpoint: [main] - job_name: pure_exporter_policies metrics_path: /metrics/policies static_configs: - targets: ['<%= @hostname %>:9491'] labels: environment: 'production' job: pure_exporter params: endpoint: [main] # From the tokens configuration above We also configure some metric_relabel_configs to extract labels from name using regex. Those labels help reduce the complexity of queries that aggregate metrics by different components. Detailed documentation on the available metrics can be found here. Alerts Auto Generated Alerts As I shared earlier, the system has an internal Alerting module that automatically triggers alerts for critical situations and creates tickets. To cover those alerts on the Prometheus side, we added an alerting configuration of our own that relies on the incoming severities: - alert: PureAlert annotations: summary: '{{ $labels.summary }}' description: '{{ $labels.component_type }} - {{ $labels.component_name }} - {{ $labels.action }} - {{ $labels.kburl }}' dashboard: 'https://grafana/your-dashboard' expr: purefb_alerts_open{environment="production"} == 1 for: 1m We still need to evaluate how the pure-generated alerts will interact with the custom alerts I will cover below, and we might decide to stick to one or the other depending on what we find out. Hardware Before I continue, the image below helps visualize how some of the Pure FlashBlade components are physically organized: Because of Pure’s reliability, most isolated hardware failures do not require the immediate attention of an Ops team member. To cover the most basic hardware failures, we configure an alert that sends a message to the Ops Basecamp 4 project chat: - alert: PureHardwareFailed annotations: summary: Hardware {{ $labels.name }} in chassis {{ $labels.ch }} is failed description: 'The Pure Storage hardware {{ $labels.name }} in chassis {{ $labels.ch }} is failed' dashboard: 'https://grafana/your-dashboard' expr: purefb_hardware_health == 0 for: 1m labels: severity: chat-notification We also configure alerts that check for multiple hardware failures of the same type. This doesn’t mean two simultaneous failures will result in a critical state, but it is a fair guardrail for unexpected scenarios. We also expect those situations to be rare, keeping the risk of causing unnecessary noise low. - alert: PureMultipleHardwareFailed annotations: summary: Pure chassis {{ $labels.ch }} has {{ $value }} failed {{ $labels.type }} description: 'The Pure Storage chassis {{ $labels.ch }} has {{ $value }} failed {{ $labels.type }}, close to the healthy limit of two simultaneous failures. Ensure that the hardware failures are being worked on' dashboard: 'https://grafana/your-dashboard' expr: count(purefb_hardware_health{type!~"eth|mgmt_port|bay"} == 0) by (ch,type,environment) > 1 for: 1m labels: severity: page # We are looking for multiple failed bays in the same blade - alert: PureMultipleBaysFailed annotations: summary: Pure chassis {{ $labels.ch }} has fb {{ $labels.fb }} with {{ $value }} failed bays description: 'The Pure Storage chassis {{ $labels.ch }} has fb {{ $labels.fb }} with {{ $value }} failed bays, close to the healthy limit of two simultaneous failures. Ensure that the hardware failures are being worked on' dashboard: 'https://grafana/your-dashboard' expr: count(purefb_hardware_health{type="bay"} == 0) by (ch,type,fb,environment) > 1 for: 1m labels: severity: page Finally, we configure high-level alerts for chassis and XFM failures: - alert: PureChassisFailed annotations: summary: Chassis {{ $labels.name }} is failed description: 'The Pure Storage hardware chassis {{ $labels.name }} is failed' dashboard: 'https://grafana/your-dashboard' expr: purefb_hardware_health{type="ch"} == 0 for: 1m labels: severity: page - alert: PureXFMFailed annotations: summary: Xternal Fabric Module {{ $labels.name }} is failed description: 'The Pure Storage hardware Xternal fabric module {{ $labels.name }} is failed' dashboard: 'https://grafana/your-dashboard' expr: purefb_hardware_health{type="xfm"} == 0 for: 1m labels: severity: page Latency Using the metric purefb_array_performance_latency_usec we can set a threshold for all the different protocols and dimensions (read, write, etc), so we are alerted if any problem causes the latency to go above an expected level. - alert: PureLatencyHigh annotations: summary: Pure {{ $labels.dimension }} - {{ $labels.protocol }} latency high description: 'Pure {{ $labels.protocol }} latency for dimension {{ $labels.dimension }} is above 100ms' dashboard: 'https://grafana/your-dashboard' expr: (avg_over_time(purefb_array_performance_latency_usec{protocol="all"}[30m]) * 0.001) for: 1m labels: severity: chat-notification Saturation For saturation, we are primarily worried about something unexpected causing excessive use of array space, increasing the risk of hitting the cluster capacity. With that in mind, it’s good to have a simple alert in place, even if we don’t expect it to fire anytime soon: - alert: PureArraySpace annotations: summary: Pure Cluster {{ $labels.instance }} available space is expected to be below 10% description: 'The array space for pure cluster {{ $labels.instance }} is expected to be below 10% in a month, please investigate and ensure there is no risk of running out of capacity' dashboard: 'https://grafana/your-dashboard' expr: (predict_linear(purefb_array_space_bytes{space="empty",type="array"}[30d], 730 * 3600)) < (purefb_array_space_bytes{space="capacity",type="array"} * 0.10) for: 1m labels: severity: chat-notification HTTP We use BigIp load balancers to front-end the cluster, which means that all the alerts we already had in place for the BigIp HTTP profiles, virtual servers, and pools also cover access to Pure. The solution for each organization on this topic will be different, but it is a good practice to keep an eye on HTTP status codes and throughput. Grafana Dashboards The project’s GitHub repository includes JSON files for Grafana dashboards that are based on the metrics generated by the exporter. With simple adjustments to fit each setup, it’s possible to import them quickly. Wrapping up On top of the system’s built-in capabilities, Pure also provides options to integrate their system into well-known tools like Prometheus and Grafana, facilitating the process of managing the cluster the same way we manage everything else. I hope this post helps any other team interested in working with them better understand the effort involved. Thanks for reading!

4 months ago 64 votes
Announcing Hotwire Spark: live reloading for Rails applications

Today, we are releasing Hotwire Spark, a live-reloading system for Rails Applications. Reloading the browser automatically on source changes is a problem that has been well-solved for a long time. Here, we wanted to put an accent on smoothness. If the reload operation is very noticeable, the feedback loop is similar to just reloading the page yourself. But if it’s smooth enough—if you only perceive the intended change—the feedback loop becomes terrific. To use, just install the gem in development: group :development do gem "hotwire-spark" end It will update the current page on three types of change: HTML content, CSS, and Stimulus controllers. How do we achieve that desired smoothness with each? For HTML content, it morphs the <body> of the page into the new <body>. Also, it disconnects and reconnects all the Stimulus controllers on the page. For CSS, it reloads the changed stylesheet. For Stimulus controllers, it fetches the changed controller, replaces its module in Stimulus, and reconnects all the controllers. We designed Hotwire Spark to shine with the #nobuildapproach we use and recommend. Serving CSS and JS assets as standalone files is ideal when you want to fetch and update only what has changed. There is no need to use bundling or any tooling. Hot Module Replacement for Stimulus controllers without any frontend building tool is pretty cool! 2024 has been a very special year for Rails. We’re thrilled to share Hotwire Spark before the year wraps up. Wishing you all a joyful holiday season and a fantastic start to 2025.

5 months ago 89 votes
A vanilla Rails stack is plenty

If you have the luxury of starting a new Rails app today, here’s our recommendation: go vanilla. Fight hard before adding Ruby dependencies. Keep that Gemfile that Rails generates as close to the original one as possible. Fight even harder before adding Javascript dependencies. You don’t need React or any other front-end frameworks, nor a JSON API to feed those. Hotwire is a fantastic, pragmatic, and ridiculously productive technology for the front end. Use it. The same goes for mobile apps: use Hotwire Native. With a hybrid approach you can combine the very same web app you have built with a wonderful native experience right where you want it. The productivity compared to a purely native approach is night and day. Embrace and celebrate rendering things on the server. It has become cool again. ERB templates and view helpers will take you as long as you need, and they are a fantastic common ground for designers to collaborate hands-on with the code. #nobuild is the simplest way to go; don’t close this door with your choices. Instead of bundling Javascript, use import maps. Don’t bundle CSS, just use modern standard CSS goodies and serve them all with Propshaft. If you have 100 Javascript files and 100 stylesheets, serve 200 standalone requests multiplexed over HTTP2. You will be delighted. Don’t add Redis to the mix. Use solid_cache for caching, solid_queue for jobs, and solid_cable for Action Cable. They will all work on your beloved relational database and are battle-tested. Test your apps with Minitest. Use fixtures and build a realistic set of those as you cook your app. Make your app a PWA, which is fully supported by Rails 8. This may be more than enough before caring about mobile apps at all. Deploy your app with Kamal. If you want heuristics, your importmap.rb should import Turbo, Stimulus, your app controllers, and little else. Your Gemfile should be almost identical to the one that Rails generates. I know it sounds radical, but going vanilla is a radical stance in this convoluted world of endless choices. This is the Rails 8 stack we have chosen for our new apps at 37signals. We are a tiny crew, so we care a lot about productivity. And we sell products, not stacks, so we care a lot about delighting our users. This is our Omakase stack because it offers the optimal balance for achieving both. Vanilla means your app stays nimble. Fewer dependencies mean fewer future headaches. You get a tight integration out of the box, so you can focus on building things. It also maximizes the odds of having smoother future upgrades. Vanilla requires determination, though, because new dependencies always look shiny and shinier. It’s always clear what you get when you add them, but never what you lose in the long term. It is certainly up to you. Rails is a wonderful big tent. These are our opinions. If it resonates, choose vanilla! Guess what our advice is for architecting your app internals?

5 months ago 47 votes
Mission Control — Jobs 1.0 released

We’ve just released Mission Control — Jobs v1.0.0, the dashboard and set of extensions to operate background jobs that we introduced earlier this year. This new version is the result of 92 pull requests, 67 issues and the help of 35 different contributors. It includes many bugfixes and improvements, such as: Support for Solid Queue’s recurring tasks, including running them on-demand. Support for API-only apps. Allowing immediate dispatching of scheduled and blocked jobs. Backtrace cleaning for failed jobs’ backtraces. A safer default for authentication, with Basic HTTP authentication enabled and initially closed unless configured or explicitly disabled. Recurring tasks in Mission Control — Jobs, with a subset of the tasks we run in production We use Mission Control — Jobs daily to manage jobs HEY and Basecamp 4, with both Solid Queue and Resque, and it’s the dashboard we recommend if you’re using Solid Queue for your jobs. Our plan is to upstream some of the extensions we’ve made to Active Job and continue improving it until it’s ready to be included by default in Rails together with Solid Queue. If you want to help us with that, are interested in learning more or have any issues or questions, head over to the repo in GitHub. We hope you like it!

5 months ago 43 votes

More in programming

HEY is finally for sale on the iPhone!

Our battle with Apple over their gangster attempt to extort 30% of our HEY revenues was one of the defining moments of my career. It was the kind of test that calls you to account for what you believe and asks what you're willing to risk to see it through. Well, we risked everything, but also secured a four-year truce, and now near-total victory is at hand: HEY is finally for sale on the iPhone in the US! Credit for this amazing turn of events goes to Epic Games founders Tim Sweeney and Mark Rein, who did what no small developer like us could ever dream of doing: they spent over $100 million to sue Apple in court. And while the first round yielded very little progress, Apple's (possibly criminal) contempt of court is what ultimately delivered the resolution. Thanks to their fight for Fortnite, app developers everywhere are now allowed to link out of apps to their own web-based payment system in the US store (but, sadly, nowhere else yet). This is all we ever wanted from Apple: to have a way to distribute our iPhone apps and keep the customer relationship by billing directly. The 30% toll gets all the attention, and it is ludicrously egregious, but to us, it's just as much about retaining that direct customer relationship, so we can help folks with refunds, so they don't tie their billing for a multi-platform email system to a single manufacturer. Apple always claims to put the needs of the users first, and that whatever hardship developers have to carry is justified by their customer-focused obsession. But in this case, it's clear that the obsession was with collecting the easiest billions Apple has ever made, by taking an obscene cut of all software and subscription sales on the platform. This obsession with squeezing every last dollar from developers has produced countless customer-hostile experiences on the iPhone. Like how you couldn't buy a book in the Kindle app before this (now you can!). Or sign up for a Netflix subscription (now you can!). Before, users would hunt in vain for an explanation inside these apps, and thanks to Apple's gag orders, developers were not even allowed to explain the confusing situation. It's been the same deal with HEY. While we successfully fought off Apple's attempt to extort us into using their in-app payment system (IAP), we've been stuck with an awkward user experience ever since. One that prevented new customers from signing up for a real email address in the application, and instead sent them down this bizarre burner-account setup. All so the app would "do something", in order to please an argument that App Store chief Phil Schiller made up on the fly in an interview. That's what we can now get rid of. No more weird burner accounts. Now you can sign up directly for a real email address in HEY, and if you like what we have to offer (and I think you will!), you'll be able to pay the $99/year for a subscription via a web-based flow that it's now kosher to link to from the app itself. What a journey, and what a needless torching of the developer relationship from Apple's side. We've always been happy to pay Apple for hosting our application on the App Store, as all developers have always needed to do via the $99/year developer fee. But being forced to hand over 30% of the business, as well as the direct customer relationship, was always an unacceptable overreach. Now that's been arrested by Judge Yvonne Gonzalez Rogers from the United States District Court of Northern California, who has delivered app developers the only real relief that we've seen in this whole sordid monopoly affair that's been boiling since 2020. It's a beautiful thing. It also offers Apple an opportunity to bury the hatchet with developers. They can choose to accept the court's decision in full and worldwide. Allow developers everywhere the right to link to their own billing flow, so they can retain their own customer relationship, and so business models that can't carry a 30% toll can flourish. Besides, Apple's own offering will likely still have plenty of pull. I'm sure many small developers would continue to consider IAP to avoid having to worry about international taxes or even direct customer service. Nobody is taking that away from Apple or those developers. All Judge Rogers is demanding is that Apple compete fairly with alternative arrangements. In case Apple doesn't accept the court's decision — and there's sadly some evidence to that — I hope the European antitrust regulators watch the simple yet powerful mechanism that Judge Rogers has imposed on Apple. While I'd love side loading as much as the next sovereign techie who wants to own the hardware I buy, I think we can get the lion's share of independence by simply being allowed to link out of the apps, just like has been so ordered by this District Court. I do hope, though, that Apple does accept the court's decision. Both because it would be a stain on their reputation to get convicted of criminal contempt of court, but also because I really want Apple to return to being a shining city on the hill. To show that you can win in the market merely by making better products. Something Apple never used to be afraid of doing. That they don't need these gangster extortion techniques to make the numbers that Cook has promised Wall Street. Despite moving on to Linux and Android, I have a real soft spot for Apple's taste, aesthetics, and engineering prowess. They've lost their way and moral compass over the last half decade or so, but that's only one leadership pivot away from being found again. That won't win back all the trust and good faith that was squandered right away, but they'll at least be on the long road to recovery. Who knows, maybe developers would even be inclined to assist Apple next time they need help launching a new device in need of third-party software to succeed.

23 hours ago 2 votes
Product Pseudoscience

In his post about “Vibe Drive Development”, Robin Rendle warns against what I’ll call the pseudoscientific approach to product building prevalent across the software industry: when folks at tech companies talk about data they’re not talking about a well-researched study from a lab but actually wildly inconsistent and untrustworthy data scraped from an analytics dashboard. This approach has all the theater of science — “we measured and made decisions on the data, the numbers don’t lie” etc. — but is missing the rigor of science. Like, for example, corroboration. Independent corroboration is a vital practice of science that we in tech conveniently gloss over in our (self-proclaimed) objective data-driven decision making. In science you can observe something, measure it, analyze the results, and draw conclusions, but nobody accepts it as fact until there can be multiple instances of independent corroboration. Meanwhile in product, corroboration is often merely a group of people nodding along in support of a Powerpoint with some numbers supporting a foregone conclusion — “We should do X, that’s what the numbers say!” (What’s worse is when we have the hubris to think our experiments, anecdotal evidence, and conclusions should extend to others outside of our own teams, despite zero independent corroboration — looking at you Medium articles.) Don’t get me wrong, experimentation and measurement are great. But let’s not pretend there is (or should be) a science to everything we do. We don’t hold a candle to the rigor of science. Software is as much art as science. Embrace the vibe. Email · Mastodon · Bluesky

18 hours ago 1 votes
Can Directories Rise Again?

With search getting worse by the day, maybe it's time we rebounded in the other direction. The long forgotten directory. The post Can Directories Rise Again? appeared first on The History of the Web.

3 hours ago 1 votes
Is There a Japanese Equivalent of Glassdoor?

When interviewing with a Japanese company, you’ll naturally want to know: “Is this a good place to work?” And while Glassdoor is the standard in English-speaking countries for employees leaving online reviews, the site is only rarely used in Japan, and then primarily by non-Japanese workers. Many countries have a culture that endorses directly reviewing employers in an open, public environment—Japan does not. However, there are still sites where you can find important information on your potential employer. What to watch out for In particular, you want to avoid signing on with a company that engages in exploitative practices—or as they’re known in Japan, a “black company” (ブラック企業, burakku kigyou). The Ministry of Health, Labor, and Welfare has a FAQ describing what defines these companies: Imposing extremely long working hours with high quotas. Recognition of workers’ rights is low throughout the company; unpaid overtime and/or workplace bullying (パワハラ, pawahara) are common. The company assigns shifts to workers without consent. The company discriminates among workers in the above circumstances. In a 2023 survey, those who had worked for such toxic companies listed high turnover rates as the most common sign that something was wrong, followed by long working hours and unpaid overtime. As you examine online review sites and other sources, look for clues such as: Turnover rate: how long do employees typically stay? Internal promotion: can you see employees rising in the ranks? Upper management: are there any non-Japanese employees in management positions? Recent company announcements: do they often make sudden pivots in their business policies? If you discover, for example, that the company can’t retain employees, shows no history of internal promotions, and has just issued a return-to-office order out of the blue, it’s safe to assume you don’t want to work there. OpenWork OpenWork, also known as Vorkers, hosts over 19 million company reviews. The reviews are represented in a radar chart for easy visual reference, and are also broken down into different categories, such as work-life balance, the ease of working for women, and reasons for considering quitting. In addition, applicants can post questions for employees to answer. If you don’t speak Japanese, the site is still readable with Google Translate. You’ll need to make a free account to see all of the information, but much of it is accessible even without an account. Other Japanese sites JobTalk and Engage Hyouban are other Japanese-language review sites. JobTalk contains 4.4 million reviews of around 230,000 different companies, and Engage Hyouban boasts 30 million reviews for 220,000 companies. Neither of these sites offer as much information on tech companies in Japan as OpenWork does. If you’re applying to a large company such as Rakuten, you may find some additional reviews there, but many of TokyoDev’s clients are smaller companies that aren’t listed at all. Google Maps Reviews An unusual but occasionally helpful place to find company reviews is on Google Maps. If you search for a business’s main corporate office location—usually in Tokyo—you will sometimes find reviews written by current or former employees. Whether these reviews are high-quality or trustworthy is another matter. Rakuten, for example, has reviews with a range of opinions. Cybozu, by contrast, mostly has reviews from those who would like to work for the company but currently don’t. Still, the reviews of its corporate office are consistently positive, so you can at least get an impression of the physical environment. LinkedIn “If you’re worried that a company might be a poor place to work, try contacting current or past employees via LinkedIn,” suggested Paul McMahon, founder of TokyoDev. “This probably works best if you’re late in the hiring process.” You can send a connect request saying, ‘I’ve received an offer from company X, and want to confirm what it’s really like to work there as an engineer. Mind if I ask you a couple of questions?’ Whether or not they respond, you can still glean good information from the profiles of past and current employees. Check to see if developers tend to leave the company quickly, for example, or how long the average employee goes before being promoted. You should keep in mind though that LinkedIn is not popular in Japan, for several good reasons. If you are applying to a primarily Japanese company, many of your future coworkers won’t be active there, which means you still may not be getting a complete picture. TokyoDev In 2020, TokyoDev began interviewing developers in order to provide a more complete, boots-on-the-ground picture of daily life at specific companies. Our Developer Stories feature interviews with developers at top Japanese tech companies, who share details about both their specific jobs and the general work environment. The goal is to give applicants a good sense of how a company operates on a day-to-day basis, from the perspective of those on the inside. So far, TokyoDev has interviewed developers from Mercari, PayPay, Givery, HENNGE, KOMOJU, and more. In addition, TokyoDev’s job board is a selective one, listing only companies that we feel good about sending applicants to. In the rare event that employees later reach out with poor reviews of a business, if those reports can be confirmed, then TokyoDev will end its relationship with that company. Conclusion In short, the answer to the question “Is there a Japanese equivalent to Glassdoor?” is, “Not really.” However, by combining some of the alternatives—OpenWork, LinkedIn, TokyoDev, and perhaps even Google Maps—you can gather enough information to decide whether you want to work with a particular Japanese company. You could also ask fellow developers in our Discord. Curious about working in Japan in general? See our articles on the subject, as well as moving to Japan, living in Japan, starting a business in Japan, and more.

yesterday 2 votes
Server Componets (RSC) in react-router are... actually good? (tip)

Explore Remix's new React Server Components (RSC) preview in react-router! Learn usage, different approaches, and trade-offs.

2 days ago 7 votes