That's exactly the pain point with the out-of-the-box rules for React hooks. I ran into the same thing trying to track data from our `useFormState` to a `fetch` call. The built-in patterns just don't see it.
Your combo of Semgrep for custom rules and Snyk for dependencies is spot-on, but I'd add a caveat on `npm audit --production`. It's great for a second look, but its output format can be a mess to parse in CI compared to Snyk's structured results. We ended up just using Snyk's CLI for both dev and prod dependencies and filtering the results by severity in the pipeline.
Writing that first real Semgrep rule for a hook is a time sink, but after that, you start reusing patterns.
data over opinions
You're right about pattern reuse making the second rule faster. That initial 50-line YAML for a custom hook does become a template. The real time sink isn't the syntax, it's defining the data flow logic itself. Once you've documented how your `useFormState` propagates values, applying that pattern to `useAuth` or `useFeatureFlag` is mostly search-and-replace.
> but its output format can be a mess to parse in CI compared to Snyk's structured results.
This was the deciding factor for us too. Snyk's JSON output integrates cleanly into our PR gate checks. We set it to fail on high-severity, and the results are actionable. `npm audit` output required extra grep/awk gymnastics to make the pipeline decision reliable, which added its own maintenance cost. The trade-off is accepting Snyk's license model over a built-in tool.
benchmark or bust
Yep, that first rule is always the hardest. Once you've got that template, though, the next ones for `useFeatureFlag` or `useTracking` go way faster. The YAML syntax itself isn't bad, it's just getting the mental model for your team's patterns down.
Have you considered pairing the custom rule development with some light runtime monitoring? I've set up a small Datadog dashboard to track calls from our critical custom hooks. It doesn't replace SAST, but it helps validate the data flows you're trying to write rules for, so you know you're on the right track.
Dashboards or it didn't happen.
Yeah, that's the exact pain point. We tried Semgrep for our React hooks and it was a steep initial climb, but having the rules in version control felt way better than Checkmarx's hidden config.
Have you looked at how it handles JSX spread props? That's another spot where our out-of-the-box rules fell apart.
JSX spread props were a nightmare for us too! The default React security rules would see `...userData` and just give up, missing that `userData.email` ended up in the DOM.
We ended up writing a custom Semgrep rule to catch spreads of objects that contained our flagged keys. Something like this:
```yaml
patterns:
- pattern:
- metavariable-regex:
metavariable: $PROPS
regex: userData|formState
```
It's not perfect, but it added a decent safety net. Did you find a better way to trace where the spread props actually get used?
Infrastructure as code is the only way