Begin with domain experience, not the size of the portfolio. Ask to see a couple of projects that resemble your domain and your stack, and then find out whether those engineers are still with the company. A serious vendor will put you on a call with the people who would work on your project. Vague answers at this stage generally mean the demo work came from somewhere else.
The paperwork needs more scrutiny than the proposal. A few clauses carry most of the weight: intellectual property assignment, non-disclosure, and laravel vs nodejs notice periods and handover. All the work product should transfer to you on payment, including designs, scripts and infrastructure configuration. Look closely at language that leaves so-called reusable libraries in the vendor’s hands, as that is often the dependency that makes switching painful.
Ask where their numbers come from. A serious estimate comes with a list of assumptions, a task-level breakdown and an explicit range. A fixed-price contract works only when the scope is genuinely frozen; otherwise the vendor pads the number and you fund the buffer regardless. Time and materials moves the risk back to the client, laravel vs next.js so it demands a sprint cadence, demos and laravel vs symfony a budget cap.
The delivery process matters as much as team size. Ask how change requests are handled, who writes the acceptance criteria and how quality assurance works. A well-run team will be able to walk you through a working build every one or software development lifecycle stages two weeks. Acceptance criteria in writing stay the only reliable protection against endless rounds of rework.
Finally, think about the end of the engagement at the start rather than at the end. Ask that the code repository lives under your account from the beginning, and that the documentation is refreshed in every sprint. A vendor with nothing to hide says yes immediately; hesitation here tells you quite a lot.