建文元年(1399年)冬,靖难之役的战火已燃至北平周边。十月十九日,燕王朱棣在会州(今河北平泉)对麾下军队进行了一次关键整编,确立了中、前、左、右、后五军体系。仅仅两日后,燕军便挥师进入松亭关(今河北宽城西南),展现出其主动出击的凌厉态势。
十一月初五,时值严冬,白河(流经今北京顺义东部)水面已完全封冻。朱棣敏锐地抓住了这一自然条件带来的战机,果断率军踏冰渡河。渡河后不久,燕军先锋便与南军大将李景隆派出的哨探部队遭遇。这支由都督陈晖率领的万余人马,本欲侦察燕军动向,却反被以逸待劳的燕军击溃。此战不仅扫清了前进障碍,更极大地提振了燕军士气,为接下来的决战拉开了序幕。
就在初五当天,燕军主力与李景隆统率的主力大军在郑村坝(今北京东郊)正面相遇。面对兵力占据优势的南军,朱棣并未选择固守,而是主动发起进攻。他指挥燕军从左右两翼进行迅猛冲击,利用骑兵的机动性反复撕扯南军阵线。激战之中,燕军竟连续攻破南军七座大营,致使南军阵脚大乱。
战至夜晚,李景隆见大势已去,为免全军覆没,竟下令郑村坝全军丢弃辎重,轻装连夜南撤。这一仓促决定导致数十万大军的粮草、器械尽数落入燕军之手。更为致命的是,李景隆的撤退命令未能及时传达给仍在围攻北平城的其余南军部队。于是,城内的燕军留守部队趁势杀出,与朱棣回师的主力里应外合,轻松击溃了城下懵然不知的南军,并缴获了大量物资。
郑村坝一役,南军损失超过十万人,主帅李景隆一路败退至德州。朱棣则于十一月初九凯旋回到北平。此战后,朱棣再次上书朝廷,指斥齐泰、黄子澄为祸乱之源,但建文帝仍未回应。同年十二月,朱棣巧施反间计,使朝廷削去辽东守将吴高的爵位,成功消除了东北方向的潜在威胁。
鉴于李景隆溃败后需时间重整,并可能待来年春季再图北进,朱棣决定化被动为主动,开辟新战场。十二月十九日,他挥师西进,佯攻军事重镇大同。此举意图正在于“攻其必救”,调动南军。果然,李景隆被迫率军离开相对温暖的山东,顶风冒雪驰援大同。而当南军疲惫不堪地赶到紫荆关一带时,朱棣已率燕军从容地从居庸关返回北平。南军这次徒劳无功的千里奔波,非但未能接战,反而在严寒中折损了大量兵员与装备,士气跌落谷底。
建文二年(1400年)二月末,无力再战的李景隆不得不致信朱棣请求休战。朱棣则顺势提出交出齐泰、黄子澄等条件。此次战略机动,燕军不仅疲惫消耗了南军,还在途中意外收编了一支蒙古降军,进一步增强了实力。与此同时,保定府也于此时归附燕王,燕军的势力与声望在此消彼长中持续增长。